# esbuild\r
build/\r
dist/\r
+\r
+# IDE\r
+.vscode\r
--- /dev/null
+<!--
+SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
+SPDX-License-Identifier: GPL-3.0-or-later
+-->
+
+PASS Original PoW module: Time to calculate proof-of-work for a send block 16 times
+Total: 89756 ms
+Average: 5609.75 ms
+Harmonic: 2092.567565254879 ms
+Geometric: 3612.112662613675 ms
+
+PASS Customized PoW: Time to calculate proof-of-work for a send block 16 times
+Total: 33240 ms
+Average: 2077.5 ms
+Harmonic: 1328.5635414262717 ms
+Geometric: 1663.110986923899 ms
+
+How much faster?
+Total: 56156 ms
+Average: 3532 ms
+Harmonic: 764 ms
+Geometric: 1949 ms
+
+Another PowGl test:
+Total: 22831.300000041723 ms
+Average: 3805.2166666736207 ms
+Harmonic: 928.6432328540742 ms
+Geometric: 2500.810238375608 ms
+Minimum: 193 ms
+Maximum: 8361 ms
+
+The proof-of-work equation for Nano cryptocurrency is defined as `blake2b(nonce||blockhash)>=threshold` where blake2b is the hash function configured for an 8-byte output, nonce is a random 8-byte value, || is concatenation, blockhash is a 32-byte value, and threshold is 0xfffffff800000000.
+
+My code currently finds valid nonces on a gaming GPU without issue but only because the initial search space is so large due to using a workgroup size of 256 and a dispatch of (256, 256, 256), so the probability of finding a nonce in the first pass is extremely high. However, this does not perform well on less powerful hardware like smartphones. Please alter my code to perform the nonce search in `main()` in a loop until a valid nonce is found with the idea that a smaller workgroup size and/or smaller dispatch dimensions can allow weak hardware to nonetheless iterate through nonces to search for a valid one and return it.
+
+
+Total: 680948 ms
+Average: 1329.9765625 ms
+Harmonic: 749.6552658409396 ms
+PASS Customized PoW: Time to calculate proof-of-work for a send block 512 times
+
+
+
+CHROMIUM with more accurate timings
+
+PowGpu: Time to calculate proof-of-work for a send block 8192 times
+Total: 2934170.3000008166 ms
+Average: 358.17508544931843 ms
+Harmonic: 218.11823673331645 ms
+Minimum: 76.2000000178814 ms
+Maximum: 2999.9000000059605 ms
+
+
+
+PowGpu: Time to calculate proof-of-work for a send block 512 times
+Total: 187428.40000000596 ms
+Average: 366.07109375001164 ms
+Harmonic: 220.70399520519166 ms
+
+PowGpu: Time to calculate proof-of-work for a send block 512 times
+Total: 187827.7999998629 ms
+Average: 366.85117187473224 ms
+Harmonic: 223.9897252426498 ms
+
+libnemo: Time to calculate proof-of-work for a send block 512 times
+(after inlining entire first G round)
+Total: 156981.3999993205 ms
+Average: 306.60429687367287 ms
+Harmonic: 128.74904701127866 ms
+Minimum: 21.700000047683716 ms
+Maximum: 1981.199999988079 ms
+
+libnemo: Time to calculate proof-of-work for a send block 512 times
+(after inlining entire first G round)
+Total: 162225.30000036955 ms
+Average: 316.8462890632218 ms
+Harmonic: 130.50451885939313 ms
+Geometric: 211.25671228925867 ms
+Minimum: 21.600000023841858 ms
+Maximum: 2267.600000023842 ms
+
+libnemo: Time to calculate proof-of-work for a send block 512 times
+(after inlining 3 rounds of G mixing)
+Total: 155547.09999996424 ms
+Average: 303.80292968743015 ms
+Harmonic: 118.19131857240315 ms
+Geometric: 196.77234360098842 ms
+Minimum: 19.5 ms
+Maximum: 2140.2000000476837 ms
+
+libnemo: Time to calculate proof-of-work for a send block 512 times
+(after inlining 5 rounds of G mixing)
+Total: 165145.19999998808 ms
+Average: 322.5492187499767 ms
+Harmonic: 126.40822610460997 ms
+Geometric: 205.28427810986508 ms
+Minimum: 20.099999964237213 ms
+Maximum: 1850.5 ms
+
+libnemo: Time to calculate proof-of-work for a send block 512 times
+(after inlining 5 rounds of G mixing and replacing if with select in original G function)
+Total: 135665.40000021458 ms
+Average: 264.9714843754191 ms
+Harmonic: 118.80915172412905 ms
+Geometric: 181.19191881133972 ms
+Minimum: 19.599999964237213 ms
+Maximum: 1908.5 ms
+
+libnemo: Time to calculate proof-of-work for a send block 512 times
+(after inlining 9 rounds of G mixing and replacing if with select in original G function)
+Total: 147481.09999907017 ms
+Average: 288.0490234356839 ms
+Harmonic: 122.25335314983455 ms
+Geometric: 192.75325397221323 ms
+Minimum: 22.19999998807907 ms
+Maximum: 1762.800000011921 ms
+
+libnemo: Time to calculate proof-of-work for a send block 512 times
+(after inlining all rounds of G mixing)
+Total: 165041.20000058413 ms
+Average: 322.34609375114087 ms
+Harmonic: 121.30652845909019 ms
+Geometric: 202.80092012876665 ms
+Minimum: 21.69999998807907 ms
+Maximum: 2303 ms
+
+libnemo: Time to calculate proof-of-work for a send block 512 times
+(after inlining all rounds of G mixing and all if statements replaced with select function)
+Total: 134865.20000064373 ms
+Average: 263.4085937512573 ms
+Harmonic: 108.28019222737286 ms
+Geometric: 171.8797089689105 ms
+Minimum: 20.80000001192093 ms
+Maximum: 2093.199999988079 ms
+
+libnemo: Time to calculate proof-of-work for a send block 512 times
+(after increasing workgroup_size to 256 from 64 and decreasing dispatch size)
+Total: 149857.0999999717 ms
+Average: 292.6896484374447 ms
+Harmonic: 73.49751645489904 ms
+Geometric: 174.9560632035056 ms
+Minimum: 2.600000001490116 ms
+Maximum: 2364.5999999940395 ms
+
+GLOBALS.mjs:46 PASS libnemo: Time to calculate proof-of-work for a send block 512 times
+(after increasing workgroup_size to 256 from 64 and decreasing dispatch size)
+Total: 145201.70000004023 ms
+Average: 283.5970703125786 ms
+Harmonic: 54.2894989554052 ms
+Geometric: 155.58659283933008 ms
+Minimum: 2.5 ms
+Maximum: 1812.3999999985099 ms
+
+
+
+PowGpu: Time to calculate proof-of-work for a send block 32 times
+Total: 8909.500000029802 ms
+Average: 278.4218750009313 ms
+Harmonic: 191.49100480215873 ms
+Geometric: 232.13670548729021 ms
+Minimum: 76.69999998807907 ms
+Maximum: 641.5 ms
+
+PowGpu: Time to calculate proof-of-work for a send block 32 times
+Total: 11805.200000077486 ms
+Average: 368.91250000242144 ms
+Harmonic: 131.36379466491744 ms
+Geometric: 228.69384924435158 ms
+Minimum: 21.900000005960464 ms
+Maximum: 1479.5 ms
+
+libnemo: Time to calculate proof-of-work for a send block 32 times
+(after inlining three G calls)
+Total: 11208.399999916553 ms
+Average: 350.2624999973923 ms
+Harmonic: 115.78621253028925 ms
+Geometric: 210.41080264689026 ms
+Minimum: 25 ms
+Maximum: 1249.199999988079 ms
+
+libnemo: Time to calculate proof-of-work for a send block 32 times
+(after inlining entire first G round)
+Total: 9778.899999797344 ms
+Average: 305.590624993667 ms
+Harmonic: 120.65186396913916 ms
+Geometric: 193.85674573632113 ms
+Minimum: 23.69999998807907 ms
+Maximum: 1752.199999988079 ms
+
+libnemo: Time to calculate proof-of-work for a send block 32 times
+(after inlining 3 rounds of G mixing)
+Total: 10425.399999856949 ms
+Average: 325.79374999552965 ms
+Harmonic: 150.5729403997282 ms
+Geometric: 231.43806657572657 ms
+Minimum: 31.900000035762787 ms
+Maximum: 954.9000000357628 ms
+
+In the following code, look at the fourth argument. Prepend it with `v&` and remove its `u` suffix. Then insert a parameter right after it with the same name except the digit is incremented by 1. For example, `G(&v, &v0, &v1, 8u, 16u, 24u, m0, m1, m2, m3);` becomes `G(&v, &v0, &v1, &v8, &v9, 16u, 24u, m0, m1, m2, m3);`. Make sure the ampersand is present and the digits are correct as described. Do not make any other modifications.
--- /dev/null
+//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
+//! SPDX-License-Identifier: GPL-3.0-or-later
+
+import { build } from 'esbuild'
+
+await build({
+ bundle: true,
+ platform: 'browser',
+ entryPoints: [
+ { in: './src/main.ts', out: 'main.min' }
+ ],
+ format: 'esm',
+ legalComments: 'inline',
+ outdir: 'dist',
+ target: 'esnext'
+})
--- /dev/null
+//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
+//! SPDX-License-Identifier: GPL-3.0-or-later
+
+import { build } from 'esbuild'
+
+await build({
+ bundle: true,
+ platform: 'node',
+ entryPoints: [
+ { in: './src/main.ts', out: 'main.min' }
+ ],
+ format: 'esm',
+ legalComments: 'inline',
+ outdir: 'dist',
+ target: 'esnext'
+})
--- /dev/null
+SPDX-FileCopyrightText: 2025 Nano Foundation
+SPDX-License-Identifier: MIT
+<!--
+SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
+SPDX-License-Identifier: GPL-3.0-or-later
+-->
+
<!DOCTYPE html>
<head>
<link rel="icon" href="./favicon.ico">
- <script type="module" src="https://zoso.dev/?p=libnemo.git;a=blob_plain;f=global.min.js;hb=refs/heads/threads"></script>
- <script type="module" src="https://cdn.jsdelivr.net/npm/nano-webgl-pow@1.1.1/nano-webgl-pow.js"></script>
<script type="module">
(async () => {
- const times = []
- const works = document.getElementById('works')
+ let libnemo
+ try {
+ libnemo = await import('../dist/main.min.js')
+ } catch (err) {
+ console.warn(err)
+ try {
+ libnemo = await import('https://unpkg.com/libnemo/dist/main.min.js')
+ } catch (err) {
+ console.warn(err)
+ try {
+ libnemo = await import('https://cdn.jsdelivr.net/npm/libnemo/dist/main.min.js')
+ } catch (err) {
+ throw new Error(`Failed to load libnemo ${err}`)
+ }
+ }
+ }
+ function random (size = 64) {
+ let hex = ''
+ while (hex.length < size) {
+ hex += crypto.randomUUID().replace(/-.*-/g, '')
+ }
+ return hex.slice(0, size)
+ }
+ const output = document.getElementById('output')
+ const consoleGroup = console.group
+ console.group = (...args) => {
+ let a = args.join()
+ a = a.replace('%cSKIP ,color:CornflowerBlue,', '<span style="color:CornflowerBlue;font-weight:bold">SKIP </span>')
+ a = a.replace(',font-weight:bold', '</span>')
+ a = a.replace('%c', '<span style="font-weight:bold">')
+ output.innerHTML += `<pre>${a}</pre>`
+ consoleGroup(...args)
+ }
+ const consoleError = console.error
+ console.error = (...args) => {
+ let a = args.join()
+ a = a.replace('%cFAIL ,color:red,', '<span style="color:red">FAIL </span>')
+ output.innerHTML += `<pre>${a}</pre>`
+ consoleError(...args)
+ }
+ const consoleLog = console.log
+ console.log = (...args) => {
+ let a = args.join()
+ a = a.replace('%cTEST RUNNER CHECK DONE,font-weight:bold', '<span style="font-weight:bold">TEST RUNNER CHECK DONE </span>')
+ a = a.replace('%cPASS ,color:green,', '<span style="color:green">PASS </span>')
+ a = a.replace('%cSKIP ,color:CornflowerBlue,', '<span style="color:CornflowerBlue">SKIP </span>')
+ a = a.replace('%cTESTING COMPLETE,color:orange;font-weight:bold', '<span style="color:orange;font-weight:bold">TESTING COMPLETE</span>')
+ output.innerHTML += `<pre>${a}</pre>`
+ consoleLog(...args)
+ }
const block = new libnemo.SendBlock(
'nano_1e5aqegc1jb7qe964u4adzmcezyo6o146zb8hm6dft8tkp79za3sxwjym5rx',
'11618869000000000000000000000000',
'nano_1stofnrxuz3cai7ze75o174bpm7scwj9jn3nxsn8ntzg784jf1gzn1jjdkou',
'92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D'
)
- for (let i = 0; i < 0x10; i++) {
- const start = performance.now()
- await block.pow()
- const end = performance.now()
- times.push(end - start)
- works.innerHTML += `libnemo-powgl: ${block.work} (${end - start} ms)<br/>`
- console.log(block.work)
- }
- let sum = 0, reciprocals = 0, product = 1, count = times.length
- for (let i = 0; i < count; i++) {
- sum += times[i]
- reciprocals += 1 / times[i]
- product *= times[i]
- }
- const t = document.getElementById('times')
- t.innerHTML = `libnemo-powgl<br/>
-Total: ${sum} ms<br/>
-Average: ${sum / count} ms<br/>
-Harmonic: ${count / reciprocals} ms<br/>
-Geometric: ${Math.pow(product, 1 / count)} ms<br/>`
})()
</script>
- <script type="module">
- (async () => {
- const times = []
- const works = document.getElementById('works')
- for (let i = 0; i < 0x10; i++) {
- const start = performance.now()
- const work = await new Promise(resolve => {
- window.NanoWebglPow('92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D', resolve, undefined, '0xFFFFFFF8')
- })
- const end = performance.now()
- times.push(end - start)
- works.innerHTML += `nano-webgl-pow: ${work} (${end - start} ms)<br/>`
- }
- let sum = 0, reciprocals = 0, product = 1, count = times.length
- for (let i = 0; i < count; i++) {
- sum += times[i]
- reciprocals += 1 / times[i]
- product *= times[i]
- }
- const t = document.getElementById('times')
- t.innerHTML += `nano-webgl-pow<br/>
-Total: ${sum} ms<br/>
-Average: ${sum / count} ms<br/>
-Harmonic: ${count / reciprocals} ms<br/>
-Geometric: ${Math.pow(product, 1 / count)} ms<br/>`
- })()
-
- </script>
+ <script type="module" src="./test/test.main.mjs"></script>
<style>body{background:black;color:white;}</style>
</head>
<body>
- <p id="times"></p>
- <p id="works"></p>
+ <h1>libnemo</h1>
+ <p id="output"></p>
</body>
</html>
"": {
"name": "libnemo",
"version": "0.0.21",
+ "license": "(GPL-3.0-or-later AND MIT AND ISC)",
+ "dependencies": {
+ "nano-pow": "^5.1.4",
+ "nano-webgl-pow": "^1.1.1"
+ },
+ "devDependencies": {
+ "@types/node": "^24.0.4",
+ "@types/w3c-web-hid": "^1.0.6",
+ "@types/w3c-web-usb": "^1.0.10",
+ "@types/web-bluetooth": "^0.0.21",
+ "esbuild": "^0.25.5",
+ "typescript": "^5.8.3"
+ },
+ "funding": {
+ "type": "nano",
+ "url": "nano:nano_1zosoqs47yt47bnfg7sdf46kj7asn58b7uzm9ek95jw7ccatq37898u1zoso"
+ },
+ "optionalDependencies": {
+ "@ledgerhq/hw-transport-web-ble": "^6.29.7",
+ "@ledgerhq/hw-transport-webhid": "^6.30.3",
+ "@ledgerhq/hw-transport-webusb": "^6.29.7"
+ }
+ },
+ "../nano-pow": {
+ "version": "1.2.3",
+ "extraneous": true,
+ "license": "(GPL-3.0-or-later AND MIT)",
+ "devDependencies": {
+ "@types/node": "^22.10.5",
+ "@webgpu/types": "^0.1.52",
+ "esbuild": "^0.24.2",
+ "esbuild-plugin-glsl": "^1.2.2",
+ "nano-webgl-pow": "^1.1.1",
+ "typescript": "^5.7.3"
+ },
+ "funding": {
+ "type": "nano",
+ "url": "nano:nano_1zosoqs47yt47bnfg7sdf46kj7asn58b7uzm9ek95jw7ccatq37898u1zoso"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
+ "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
+ "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz",
+ "integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz",
+ "integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz",
+ "integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz",
+ "integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz",
+ "integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz",
+ "integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz",
+ "integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz",
+ "integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz",
+ "integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz",
+ "integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz",
+ "integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz",
+ "integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz",
+ "integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz",
+ "integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz",
+ "integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz",
+ "integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz",
+ "integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz",
+ "integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz",
+ "integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz",
+ "integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz",
+ "integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz",
+ "integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz",
+ "integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz",
+ "integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz",
+ "integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@ledgerhq/devices": {
+ "version": "8.4.7",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-8.4.7.tgz",
+ "integrity": "sha512-CljHIaPmtv93H2If1Zs1xW0pgg+M37bAoJkm6+V6Yw5S0MgFWFpLnTTNgCvHXyD8pG0+uq8TuOXUiG1oAV5AyA==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "@ledgerhq/errors": "^6.22.0",
+ "@ledgerhq/logs": "^6.13.0",
+ "rxjs": "^7.8.1",
+ "semver": "^7.3.5"
+ }
+ },
+ "node_modules/@ledgerhq/errors": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.22.0.tgz",
+ "integrity": "sha512-rXtpIOfHL62jWB7o77PNFD4EDYdcqyMeVgt7TZcmTkWT78cK+YYSUTMrNuGLhnZZZTMLWH023Wgt65OfKIdGBQ==",
+ "license": "Apache-2.0",
+ "optional": true
+ },
+ "node_modules/@ledgerhq/hw-transport": {
+ "version": "6.31.7",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-6.31.7.tgz",
+ "integrity": "sha512-R+QMlqoLJDPeCiqwWv85PbZ3m0hel5PwQzWwSIbyEwialqjXnG7LFQgytkgXlgMcayT0chvvLeYjuY5ZfMPY7w==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "@ledgerhq/devices": "8.4.7",
+ "@ledgerhq/errors": "^6.22.0",
+ "@ledgerhq/logs": "^6.13.0",
+ "events": "^3.3.0"
+ }
+ },
+ "node_modules/@ledgerhq/hw-transport-web-ble": {
+ "version": "6.29.7",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-web-ble/-/hw-transport-web-ble-6.29.7.tgz",
+ "integrity": "sha512-oDDPubEtKWNo5SusJOBWGQwpXlk8+8rsVoY7cqKwnEEK4hcXtbAe0y3EE/KsK+NSJtE0RfciAjfmPebybYXXPQ==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "@ledgerhq/devices": "8.4.7",
+ "@ledgerhq/errors": "^6.22.0",
+ "@ledgerhq/hw-transport": "^6.31.7",
+ "@ledgerhq/logs": "^6.13.0",
+ "rxjs": "^7.8.1"
+ }
+ },
+ "node_modules/@ledgerhq/hw-transport-webhid": {
+ "version": "6.30.3",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-webhid/-/hw-transport-webhid-6.30.3.tgz",
+ "integrity": "sha512-DV2QL4gZ3XvB5i271np5DHROu3Ry6Pjvhd65mu6JLpasAQr0VeW0L8KZ+JK9VryARC1soU1ZEPkL2uVw8MRmvg==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "@ledgerhq/devices": "8.4.7",
+ "@ledgerhq/errors": "^6.22.0",
+ "@ledgerhq/hw-transport": "^6.31.7",
+ "@ledgerhq/logs": "^6.13.0"
+ }
+ },
+ "node_modules/@ledgerhq/hw-transport-webusb": {
+ "version": "6.29.7",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-webusb/-/hw-transport-webusb-6.29.7.tgz",
+ "integrity": "sha512-6BJkgvC+8yXssD6JN5QgSKxTSLucb2Cf+dg0EJAoqNXqz84Yse3W9Z+AJVSLH6XwxH69tWtHP5VtQgltWZJA6g==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "@ledgerhq/devices": "8.4.7",
+ "@ledgerhq/errors": "^6.22.0",
+ "@ledgerhq/hw-transport": "^6.31.7",
+ "@ledgerhq/logs": "^6.13.0"
+ }
+ },
+ "node_modules/@ledgerhq/logs": {
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/logs/-/logs-6.13.0.tgz",
+ "integrity": "sha512-4+qRW2Pc8V+btL0QEmdB2X+uyx0kOWMWE1/LWsq5sZy3Q5tpi4eItJS6mB0XL3wGW59RQ+8bchNQQ1OW/va8Og==",
+ "license": "Apache-2.0",
+ "optional": true
+ },
+ "node_modules/@puppeteer/browsers": {
+ "version": "2.10.5",
+ "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.10.5.tgz",
+ "integrity": "sha512-eifa0o+i8dERnngJwKrfp3dEq7ia5XFyoqB17S4gK8GhsQE4/P8nxOfQSE0zQHxzzLo/cmF+7+ywEQ7wK7Fb+w==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "debug": "^4.4.1",
+ "extract-zip": "^2.0.1",
+ "progress": "^2.0.3",
+ "proxy-agent": "^6.5.0",
+ "semver": "^7.7.2",
+ "tar-fs": "^3.0.8",
+ "yargs": "^17.7.2"
+ },
+ "bin": {
+ "browsers": "lib/cjs/main-cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@tootallnate/quickjs-emscripten": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz",
+ "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==",
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/@types/node": {
+ "version": "24.0.4",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.4.tgz",
+ "integrity": "sha512-ulyqAkrhnuNq9pB76DRBTkcS6YsmDALy6Ua63V8OhrOBgbcYt6IOdzpw5P1+dyRIyMerzLkeYWBeOXPpA9GMAA==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~7.8.0"
+ }
+ },
+ "node_modules/@types/w3c-web-hid": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@types/w3c-web-hid/-/w3c-web-hid-1.0.6.tgz",
+ "integrity": "sha512-IWyssXmRDo6K7s31dxf+U+x/XUWuVsl9qUIYbJmpUHPcTv/COfBCKw/F0smI45+gPV34brjyP30BFcIsHgYWLA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/w3c-web-usb": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/@types/w3c-web-usb/-/w3c-web-usb-1.0.10.tgz",
+ "integrity": "sha512-CHgUI5kTc/QLMP8hODUHhge0D4vx+9UiAwIGiT0sTy/B2XpdX1U5rJt6JSISgr6ikRT7vxV9EVAFeYZqUnl1gQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/web-bluetooth": {
+ "version": "0.0.21",
+ "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz",
+ "integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/yauzl": {
+ "version": "2.10.3",
+ "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz",
+ "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
+ "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "license": "Python-2.0",
+ "optional": true
+ },
+ "node_modules/ast-types": {
+ "version": "0.13.4",
+ "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz",
+ "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/b4a": {
+ "version": "1.6.7",
+ "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz",
+ "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==",
+ "license": "Apache-2.0",
+ "optional": true
+ },
+ "node_modules/bare-events": {
+ "version": "2.5.4",
+ "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.4.tgz",
+ "integrity": "sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==",
+ "license": "Apache-2.0",
+ "optional": true
+ },
+ "node_modules/bare-fs": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.1.5.tgz",
+ "integrity": "sha512-1zccWBMypln0jEE05LzZt+V/8y8AQsQQqxtklqaIyg5nu6OAYFhZxPXinJTSG+kU5qyNmeLgcn9AW7eHiCHVLA==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "bare-events": "^2.5.4",
+ "bare-path": "^3.0.0",
+ "bare-stream": "^2.6.4"
+ },
+ "engines": {
+ "bare": ">=1.16.0"
+ },
+ "peerDependencies": {
+ "bare-buffer": "*"
+ },
+ "peerDependenciesMeta": {
+ "bare-buffer": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/bare-os": {
+ "version": "3.6.1",
+ "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.1.tgz",
+ "integrity": "sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "engines": {
+ "bare": ">=1.14.0"
+ }
+ },
+ "node_modules/bare-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz",
+ "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "bare-os": "^3.0.1"
+ }
+ },
+ "node_modules/bare-stream": {
+ "version": "2.6.5",
+ "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.6.5.tgz",
+ "integrity": "sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "streamx": "^2.21.0"
+ },
+ "peerDependencies": {
+ "bare-buffer": "*",
+ "bare-events": "*"
+ },
+ "peerDependenciesMeta": {
+ "bare-buffer": {
+ "optional": true
+ },
+ "bare-events": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/basic-ftp": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz",
+ "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/buffer-crc32": {
+ "version": "0.2.13",
+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+ "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/chromium-bidi": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-5.1.0.tgz",
+ "integrity": "sha512-9MSRhWRVoRPDG0TgzkHrshFSJJNZzfY5UFqUMuksg7zL1yoZIZ3jLB0YAgHclbiAxPI86pBnwDX1tbzoiV8aFw==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "mitt": "^3.0.1",
+ "zod": "^3.24.1"
+ },
+ "peerDependencies": {
+ "devtools-protocol": "*"
+ }
+ },
+ "node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "license": "ISC",
+ "optional": true,
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/cosmiconfig": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz",
+ "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "env-paths": "^2.2.1",
+ "import-fresh": "^3.3.0",
+ "js-yaml": "^4.1.0",
+ "parse-json": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/d-fischer"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.9.5"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/data-uri-to-buffer": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz",
+ "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/degenerator": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz",
+ "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "ast-types": "^0.13.4",
+ "escodegen": "^2.1.0",
+ "esprima": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/devtools-protocol": {
+ "version": "0.0.1464554",
+ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1464554.tgz",
+ "integrity": "sha512-CAoP3lYfwAGQTaAXYvA6JZR0fjGUb7qec1qf4mToyoH2TZgUFeIqYcjh6f9jNuhHfuZiEdH+PONHYrLhRQX6aw==",
+ "license": "BSD-3-Clause",
+ "optional": true
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/end-of-stream": {
+ "version": "1.4.5",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
+ "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "once": "^1.4.0"
+ }
+ },
+ "node_modules/env-paths": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz",
+ "integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.25.5",
+ "@esbuild/android-arm": "0.25.5",
+ "@esbuild/android-arm64": "0.25.5",
+ "@esbuild/android-x64": "0.25.5",
+ "@esbuild/darwin-arm64": "0.25.5",
+ "@esbuild/darwin-x64": "0.25.5",
+ "@esbuild/freebsd-arm64": "0.25.5",
+ "@esbuild/freebsd-x64": "0.25.5",
+ "@esbuild/linux-arm": "0.25.5",
+ "@esbuild/linux-arm64": "0.25.5",
+ "@esbuild/linux-ia32": "0.25.5",
+ "@esbuild/linux-loong64": "0.25.5",
+ "@esbuild/linux-mips64el": "0.25.5",
+ "@esbuild/linux-ppc64": "0.25.5",
+ "@esbuild/linux-riscv64": "0.25.5",
+ "@esbuild/linux-s390x": "0.25.5",
+ "@esbuild/linux-x64": "0.25.5",
+ "@esbuild/netbsd-arm64": "0.25.5",
+ "@esbuild/netbsd-x64": "0.25.5",
+ "@esbuild/openbsd-arm64": "0.25.5",
+ "@esbuild/openbsd-x64": "0.25.5",
+ "@esbuild/sunos-x64": "0.25.5",
+ "@esbuild/win32-arm64": "0.25.5",
+ "@esbuild/win32-ia32": "0.25.5",
+ "@esbuild/win32-x64": "0.25.5"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escodegen": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz",
+ "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",
+ "license": "BSD-2-Clause",
+ "optional": true,
+ "dependencies": {
+ "esprima": "^4.0.1",
+ "estraverse": "^5.2.0",
+ "esutils": "^2.0.2"
+ },
+ "bin": {
+ "escodegen": "bin/escodegen.js",
+ "esgenerate": "bin/esgenerate.js"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "optionalDependencies": {
+ "source-map": "~0.6.1"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "license": "BSD-2-Clause",
+ "optional": true,
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "license": "BSD-2-Clause",
+ "optional": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "license": "BSD-2-Clause",
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/events": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=0.8.x"
+ }
+ },
+ "node_modules/extract-zip": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
+ "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
+ "license": "BSD-2-Clause",
+ "optional": true,
+ "dependencies": {
+ "debug": "^4.1.1",
+ "get-stream": "^5.1.0",
+ "yauzl": "^2.10.0"
+ },
+ "bin": {
+ "extract-zip": "cli.js"
+ },
+ "engines": {
+ "node": ">= 10.17.0"
+ },
+ "optionalDependencies": {
+ "@types/yauzl": "^2.9.1"
+ }
+ },
+ "node_modules/fast-fifo": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
+ "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==",
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/fd-slicer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
+ "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "pend": "~1.2.0"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "license": "ISC",
+ "optional": true,
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/get-uri": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.4.tgz",
+ "integrity": "sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "basic-ftp": "^5.0.2",
+ "data-uri-to-buffer": "^6.0.2",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/http-proxy-agent": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ip-address": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz",
+ "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "jsbn": "1.1.0",
+ "sprintf-js": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsbn": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
+ "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==",
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/lru-cache": {
+ "version": "7.18.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
+ "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
+ "license": "ISC",
+ "optional": true,
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/mitt": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
+ "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/nano-pow": {
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/nano-pow/-/nano-pow-5.1.4.tgz",
+ "integrity": "sha512-pYK2JF2rW43pal0iWNFIlKDpSXA/IEe1CN59stOe0qFm4iu0/s+VvPWq6HgwZd7dEcGBJ1Rol1ZqqfcVaAieRA==",
"license": "(GPL-3.0-or-later AND MIT)",
- "devDependencies": {
- "@types/node": "^22.10.1",
- "@types/w3c-web-hid": "^1.0.6",
- "@types/w3c-web-usb": "^1.0.10",
- "@types/web-bluetooth": "^0.0.20",
- "esbuild": "^0.24.0",
- "nano-webgl-pow": "^1.1.1",
- "typescript": "^5.6.3"
+ "bin": {
+ "nano-pow": "dist/bin/nano-pow.sh"
},
"funding": {
"type": "nano",
"url": "nano:nano_1zosoqs47yt47bnfg7sdf46kj7asn58b7uzm9ek95jw7ccatq37898u1zoso"
},
"optionalDependencies": {
- "@ledgerhq/hw-transport-web-ble": "^6.29.4",
- "@ledgerhq/hw-transport-webhid": "^6.29.4",
- "@ledgerhq/hw-transport-webusb": "^6.29.4"
+ "puppeteer": "^24.10.1"
}
},
- "node_modules/@esbuild/linux-x64": {
- "version": "0.24.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz",
- "integrity": "sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
+ "node_modules/nano-webgl-pow": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/nano-webgl-pow/-/nano-webgl-pow-1.1.1.tgz",
+ "integrity": "sha512-IKAg7qx2y4n9dnT7tYYypOun/aV+35SfRxJCVnc63GboWQ5/woVIVAZcdX5VfXM1mLYBzADvXxoWZ39G3iPOFA==",
+ "license": "MIT"
+ },
+ "node_modules/netmask": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz",
+ "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==",
"license": "MIT",
"optional": true,
- "os": [
- "linux"
- ],
"engines": {
- "node": ">=18"
+ "node": ">= 0.4.0"
}
},
- "node_modules/@ledgerhq/devices": {
- "version": "8.4.4",
- "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-8.4.4.tgz",
- "integrity": "sha512-sz/ryhe/R687RHtevIE9RlKaV8kkKykUV4k29e7GAVwzHX1gqG+O75cu1NCJUHLbp3eABV5FdvZejqRUlLis9A==",
- "license": "Apache-2.0",
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "license": "ISC",
"optional": true,
"dependencies": {
- "@ledgerhq/errors": "^6.19.1",
- "@ledgerhq/logs": "^6.12.0",
- "rxjs": "^7.8.1",
- "semver": "^7.3.5"
+ "wrappy": "1"
}
},
- "node_modules/@ledgerhq/errors": {
- "version": "6.19.1",
- "resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.19.1.tgz",
- "integrity": "sha512-75yK7Nnit/Gp7gdrJAz0ipp31CCgncRp+evWt6QawQEtQKYEDfGo10QywgrrBBixeRxwnMy1DP6g2oCWRf1bjw==",
- "license": "Apache-2.0",
- "optional": true
- },
- "node_modules/@ledgerhq/hw-transport": {
- "version": "6.31.4",
- "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-6.31.4.tgz",
- "integrity": "sha512-6c1ir/cXWJm5dCWdq55NPgCJ3UuKuuxRvf//Xs36Bq9BwkV2YaRQhZITAkads83l07NAdR16hkTWqqpwFMaI6A==",
- "license": "Apache-2.0",
+ "node_modules/pac-proxy-agent": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz",
+ "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==",
+ "license": "MIT",
"optional": true,
"dependencies": {
- "@ledgerhq/devices": "^8.4.4",
- "@ledgerhq/errors": "^6.19.1",
- "@ledgerhq/logs": "^6.12.0",
- "events": "^3.3.0"
+ "@tootallnate/quickjs-emscripten": "^0.23.0",
+ "agent-base": "^7.1.2",
+ "debug": "^4.3.4",
+ "get-uri": "^6.0.1",
+ "http-proxy-agent": "^7.0.0",
+ "https-proxy-agent": "^7.0.6",
+ "pac-resolver": "^7.0.1",
+ "socks-proxy-agent": "^8.0.5"
+ },
+ "engines": {
+ "node": ">= 14"
}
},
- "node_modules/@ledgerhq/hw-transport-web-ble": {
- "version": "6.29.4",
- "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-web-ble/-/hw-transport-web-ble-6.29.4.tgz",
- "integrity": "sha512-OJyp6CryvyFlg1L9uifo5hYYdDt+WPw8/0ijBixYhYmGvlRz2W6/F2c5rG/zBQWcNnNydPOLjLJM0vR070RfCw==",
- "license": "Apache-2.0",
+ "node_modules/pac-resolver": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz",
+ "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==",
+ "license": "MIT",
"optional": true,
"dependencies": {
- "@ledgerhq/devices": "^8.4.4",
- "@ledgerhq/errors": "^6.19.1",
- "@ledgerhq/hw-transport": "^6.31.4",
- "@ledgerhq/logs": "^6.12.0",
- "rxjs": "^7.8.1"
+ "degenerator": "^5.0.0",
+ "netmask": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 14"
}
},
- "node_modules/@ledgerhq/hw-transport-webhid": {
- "version": "6.29.4",
- "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-webhid/-/hw-transport-webhid-6.29.4.tgz",
- "integrity": "sha512-XkF37lcuyg9zVExMyfDQathWly8rRcGac13wgZATBa3nZ+hUzzWr5QVKg1pKCw10izVHGErW/9a4tbb72rUEmQ==",
- "license": "Apache-2.0",
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "license": "MIT",
"optional": true,
"dependencies": {
- "@ledgerhq/devices": "^8.4.4",
- "@ledgerhq/errors": "^6.19.1",
- "@ledgerhq/hw-transport": "^6.31.4",
- "@ledgerhq/logs": "^6.12.0"
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
}
},
- "node_modules/@ledgerhq/hw-transport-webusb": {
- "version": "6.29.4",
- "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-webusb/-/hw-transport-webusb-6.29.4.tgz",
- "integrity": "sha512-HoGF1LlBT9HEGBQy2XeCHrFdv/FEOZU0+J+yfKcgAQIAiASr2MLvdzwoJbUS8h6Gn+vc+/BjzBSO3JNn7Loqbg==",
- "license": "Apache-2.0",
+ "node_modules/parse-json": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "license": "MIT",
"optional": true,
"dependencies": {
- "@ledgerhq/devices": "^8.4.4",
- "@ledgerhq/errors": "^6.19.1",
- "@ledgerhq/hw-transport": "^6.31.4",
- "@ledgerhq/logs": "^6.12.0"
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/@ledgerhq/logs": {
- "version": "6.12.0",
- "resolved": "https://registry.npmjs.org/@ledgerhq/logs/-/logs-6.12.0.tgz",
- "integrity": "sha512-ExDoj1QV5eC6TEbMdLUMMk9cfvNKhhv5gXol4SmULRVCx/3iyCPhJ74nsb3S0Vb+/f+XujBEj3vQn5+cwS0fNA==",
- "license": "Apache-2.0",
+ "node_modules/pend": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
+ "license": "MIT",
"optional": true
},
- "node_modules/@types/node": {
- "version": "22.10.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz",
- "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==",
- "dev": true,
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC",
+ "optional": true
+ },
+ "node_modules/progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
"license": "MIT",
- "dependencies": {
- "undici-types": "~6.20.0"
+ "optional": true,
+ "engines": {
+ "node": ">=0.4.0"
}
},
- "node_modules/@types/w3c-web-hid": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/@types/w3c-web-hid/-/w3c-web-hid-1.0.6.tgz",
- "integrity": "sha512-IWyssXmRDo6K7s31dxf+U+x/XUWuVsl9qUIYbJmpUHPcTv/COfBCKw/F0smI45+gPV34brjyP30BFcIsHgYWLA==",
- "dev": true,
- "license": "MIT"
+ "node_modules/proxy-agent": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz",
+ "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "^4.3.4",
+ "http-proxy-agent": "^7.0.1",
+ "https-proxy-agent": "^7.0.6",
+ "lru-cache": "^7.14.1",
+ "pac-proxy-agent": "^7.1.0",
+ "proxy-from-env": "^1.1.0",
+ "socks-proxy-agent": "^8.0.5"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
},
- "node_modules/@types/w3c-web-usb": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/@types/w3c-web-usb/-/w3c-web-usb-1.0.10.tgz",
- "integrity": "sha512-CHgUI5kTc/QLMP8hODUHhge0D4vx+9UiAwIGiT0sTy/B2XpdX1U5rJt6JSISgr6ikRT7vxV9EVAFeYZqUnl1gQ==",
- "dev": true,
- "license": "MIT"
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+ "license": "MIT",
+ "optional": true
},
- "node_modules/@types/web-bluetooth": {
- "version": "0.0.20",
- "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz",
- "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==",
- "dev": true,
- "license": "MIT"
+ "node_modules/pump": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
+ "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
},
- "node_modules/esbuild": {
- "version": "0.24.0",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.0.tgz",
- "integrity": "sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==",
- "dev": true,
+ "node_modules/puppeteer": {
+ "version": "24.11.1",
+ "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.11.1.tgz",
+ "integrity": "sha512-QbccB/LgxX4tSZRzr9KQ1Jajdvu3n35Dlf/Otjz0QfR+6mDoZdMWLcWF94uQoC3OJerCyYm5hlU2Ru4nBoId2A==",
"hasInstallScript": true,
- "license": "MIT",
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "@puppeteer/browsers": "2.10.5",
+ "chromium-bidi": "5.1.0",
+ "cosmiconfig": "^9.0.0",
+ "devtools-protocol": "0.0.1464554",
+ "puppeteer-core": "24.11.1",
+ "typed-query-selector": "^2.12.0"
+ },
"bin": {
- "esbuild": "bin/esbuild"
+ "puppeteer": "lib/cjs/puppeteer/node/cli.js"
},
"engines": {
"node": ">=18"
+ }
+ },
+ "node_modules/puppeteer-core": {
+ "version": "24.11.1",
+ "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.11.1.tgz",
+ "integrity": "sha512-I0Gv3jWBRY9E3NTBElp7br7Gaid5RbFTxCRRMHym1kCf0ompO0Pel4REGsGDwMWkg3uwFzIH7t7qXs3T4DKRWA==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "@puppeteer/browsers": "2.10.5",
+ "chromium-bidi": "5.1.0",
+ "debug": "^4.4.1",
+ "devtools-protocol": "0.0.1464554",
+ "typed-query-selector": "^2.12.0",
+ "ws": "^8.18.2"
},
- "optionalDependencies": {
- "@esbuild/aix-ppc64": "0.24.0",
- "@esbuild/android-arm": "0.24.0",
- "@esbuild/android-arm64": "0.24.0",
- "@esbuild/android-x64": "0.24.0",
- "@esbuild/darwin-arm64": "0.24.0",
- "@esbuild/darwin-x64": "0.24.0",
- "@esbuild/freebsd-arm64": "0.24.0",
- "@esbuild/freebsd-x64": "0.24.0",
- "@esbuild/linux-arm": "0.24.0",
- "@esbuild/linux-arm64": "0.24.0",
- "@esbuild/linux-ia32": "0.24.0",
- "@esbuild/linux-loong64": "0.24.0",
- "@esbuild/linux-mips64el": "0.24.0",
- "@esbuild/linux-ppc64": "0.24.0",
- "@esbuild/linux-riscv64": "0.24.0",
- "@esbuild/linux-s390x": "0.24.0",
- "@esbuild/linux-x64": "0.24.0",
- "@esbuild/netbsd-x64": "0.24.0",
- "@esbuild/openbsd-arm64": "0.24.0",
- "@esbuild/openbsd-x64": "0.24.0",
- "@esbuild/sunos-x64": "0.24.0",
- "@esbuild/win32-arm64": "0.24.0",
- "@esbuild/win32-ia32": "0.24.0",
- "@esbuild/win32-x64": "0.24.0"
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/events": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
- "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
"license": "MIT",
"optional": true,
"engines": {
- "node": ">=0.8.x"
+ "node": ">=0.10.0"
}
},
- "node_modules/nano-webgl-pow": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/nano-webgl-pow/-/nano-webgl-pow-1.1.1.tgz",
- "integrity": "sha512-IKAg7qx2y4n9dnT7tYYypOun/aV+35SfRxJCVnc63GboWQ5/woVIVAZcdX5VfXM1mLYBzADvXxoWZ39G3iPOFA==",
- "dev": true,
- "license": "MIT"
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=4"
+ }
},
"node_modules/rxjs": {
"version": "7.8.1",
}
},
"node_modules/semver": {
- "version": "7.6.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
- "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"license": "ISC",
"optional": true,
"bin": {
"node": ">=10"
}
},
+ "node_modules/smart-buffer": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
+ "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 6.0.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/socks": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.5.tgz",
+ "integrity": "sha512-iF+tNDQla22geJdTyJB1wM/qrX9DMRwWrciEPwWLPRWAUEM8sQiyxgckLxWT1f7+9VabJS0jTGGr4QgBuvi6Ww==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "ip-address": "^9.0.5",
+ "smart-buffer": "^4.2.0"
+ },
+ "engines": {
+ "node": ">= 10.0.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/socks-proxy-agent": {
+ "version": "8.0.5",
+ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz",
+ "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "^4.3.4",
+ "socks": "^2.8.3"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
+ "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
+ "license": "BSD-3-Clause",
+ "optional": true
+ },
+ "node_modules/streamx": {
+ "version": "2.22.1",
+ "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.1.tgz",
+ "integrity": "sha512-znKXEBxfatz2GBNK02kRnCXjV+AA4kjZIUxeWSr3UGirZMJfTE9uiwKHobnbgxWyL/JWro8tTq+vOqAK1/qbSA==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "fast-fifo": "^1.3.2",
+ "text-decoder": "^1.1.0"
+ },
+ "optionalDependencies": {
+ "bare-events": "^2.2.0"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/tar-fs": {
+ "version": "3.0.10",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.10.tgz",
+ "integrity": "sha512-C1SwlQGNLe/jPNqapK8epDsXME7CAJR5RL3GcE6KWx1d9OUByzoHVcbu1VPI8tevg9H8Alae0AApHHFGzrD5zA==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "pump": "^3.0.0",
+ "tar-stream": "^3.1.5"
+ },
+ "optionalDependencies": {
+ "bare-fs": "^4.0.1",
+ "bare-path": "^3.0.0"
+ }
+ },
+ "node_modules/tar-stream": {
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz",
+ "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "b4a": "^1.6.4",
+ "fast-fifo": "^1.2.0",
+ "streamx": "^2.15.0"
+ }
+ },
+ "node_modules/text-decoder": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz",
+ "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "b4a": "^1.6.4"
+ }
+ },
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"license": "0BSD",
"optional": true
},
+ "node_modules/typed-query-selector": {
+ "version": "2.12.0",
+ "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz",
+ "integrity": "sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==",
+ "license": "MIT",
+ "optional": true
+ },
"node_modules/typescript": {
- "version": "5.6.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz",
- "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==",
- "dev": true,
+ "version": "5.8.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
+ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
+ "devOptional": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
}
},
"node_modules/undici-types": {
- "version": "6.20.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
- "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
- "dev": true,
+ "version": "7.8.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",
+ "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==",
+ "devOptional": true,
"license": "MIT"
+ },
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "license": "ISC",
+ "optional": true
+ },
+ "node_modules/ws": {
+ "version": "8.18.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
+ "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "license": "ISC",
+ "optional": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs": {
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "license": "ISC",
+ "optional": true,
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yauzl": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
+ "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "buffer-crc32": "~0.2.3",
+ "fd-slicer": "~1.1.0"
+ }
+ },
+ "node_modules/zod": {
+ "version": "3.25.67",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.67.tgz",
+ "integrity": "sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw==",
+ "license": "MIT",
+ "optional": true,
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
}
}
}
],
"homepage": "https://zoso.dev",
"bugs": "bug-libnemo@zoso.dev",
- "license": "(GPL-3.0-or-later AND MIT)",
+ "license": "(GPL-3.0-or-later AND MIT AND ISC)",
"author": "Chris Duncan <chris@zoso.dev>",
"funding": {
"type": "nano",
"url": "git+https://zoso.dev/libnemo.git"
},
"scripts": {
- "build": "rm -rf dist && tsc && esbuild main.min=dist/main.js global.min=dist/global.js --outdir=dist --target=esnext --format=esm --platform=browser --bundle --sourcemap",
- "test": "npm run build && esbuild test.min=test/main.mjs --outdir=dist --target=esnext --format=esm --platform=browser --bundle --sourcemap",
- "test:node": "npm run build -- --platform=node && node --test --test-force-exit --env-file .env",
+ "build": "rm -rf {dist,types} && mkdir -p dist && tsc && mv types dist/types",
+ "build:browser": "npm run build && node esbuild-browser.mjs",
+ "build:node": "npm run build && node esbuild-node.mjs",
+ "publish": "npm test",
+ "test": "npm run build:browser",
+ "test:node": "npm run build:node && node --test --test-force-exit --env-file .env",
"test:coverage": "npm run test:node -- --experimental-test-coverage",
- "test:coverage:report": "npm run test:coverage -- --test-reporter=lcov --test-reporter-destination=coverage.info && genhtml coverage.info --output-directory test/coverage && rm coverage.info && xdg-open test/coverage/index.html",
- "test:performance": "npm run build && esbuild perf.min=perf/main.mjs --outdir=dist --target=esnext --format=esm --platform=browser --bundle --sourcemap"
+ "test:coverage:report": "npm run test:coverage -- --test-reporter=lcov --test-reporter-destination=coverage.info && genhtml coverage.info --output-directory test/coverage && rm coverage.info && xdg-open test/coverage/index.html"
},
"imports": {
- "#*": "./*"
+ "#dist/*": "./dist/*",
+ "#src/*": "./src/*",
+ "#workers": "./src/lib/workers/index.js",
+ "#workers/*": "./src/lib/workers/*"
},
"optionalDependencies": {
- "@ledgerhq/hw-transport-web-ble": "^6.29.4",
- "@ledgerhq/hw-transport-webhid": "^6.29.4",
- "@ledgerhq/hw-transport-webusb": "^6.29.4"
+ "@ledgerhq/hw-transport-web-ble": "^6.29.7",
+ "@ledgerhq/hw-transport-webhid": "^6.30.3",
+ "@ledgerhq/hw-transport-webusb": "^6.29.7"
},
"devDependencies": {
- "@types/node": "^22.10.1",
+ "@types/node": "^24.0.4",
"@types/w3c-web-hid": "^1.0.6",
"@types/w3c-web-usb": "^1.0.10",
- "@types/web-bluetooth": "^0.0.20",
- "esbuild": "^0.24.0",
- "nano-webgl-pow": "^1.1.1",
- "typescript": "^5.6.3"
+ "@types/web-bluetooth": "^0.0.21",
+ "esbuild": "^0.25.5",
+ "typescript": "^5.8.3"
},
"type": "module",
"exports": "./dist/main.js",
- "types": "dist/main.d.ts",
- "unpkg": "dist/main.min.js"
+ "types": "dist/types/main.d.ts",
+ "unpkg": "dist/main.min.js",
+ "dependencies": {
+ "nano-pow": "^5.1.4",
+ "nano-webgl-pow": "^1.1.1"
+ }
}
+++ /dev/null
-// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-'use strict'
-
-import { assert, average, skip, suite, test } from '#GLOBALS.mjs'
-import { NANO_TEST_VECTORS } from '#test/TEST_VECTORS.js'
-import { Bip44Wallet, Blake2bWallet } from '#dist/main.js'
-
-await suite('Account performance', async () => {
- await test('Time to create 0x200 BIP-44 accounts', async () => {
- const wallet = await Bip44Wallet.create(NANO_TEST_VECTORS.PASSWORD)
- await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)
- const start = performance.now()
- const accounts = await wallet.accounts(0, 0x1fff)
- const end = performance.now()
- console.log(`Total: ${end - start} ms`)
- console.log(`Average: ${(end - start) / 0x2000} ms`)
- assert.equals(accounts.length, 0x2000)
- })
-
- await test('Time to create 0x200 BLAKE2b accounts', async () => {
- const wallet = await Blake2bWallet.create(NANO_TEST_VECTORS.PASSWORD)
- await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)
- const start = performance.now()
- const accounts = await wallet.accounts(0, 0x1fff)
- const end = performance.now()
- console.log(`Total: ${end - start} ms`)
- console.log(`Average: ${(end - start) / 0x2000} ms`)
- assert.equals(accounts.length, 0x2000)
- })
-
- await test('Time to create 1 BIP-44 account 0x20 times', async () => {
- const times = []
- const wallet = await Bip44Wallet.create(NANO_TEST_VECTORS.PASSWORD)
- await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)
- for (let i = 0; i < 0x20; i++) {
- const start = performance.now()
- await wallet.accounts(i)
- const end = performance.now()
- times.push(end - start)
- }
- const { total, arithmetic, harmonic, geometric } = average(times)
- console.log(`Total: ${total} ms`)
- console.log(`Average: ${arithmetic} ms`)
- console.log(`Harmonic: ${harmonic} ms`)
- console.log(`Geometric: ${geometric} ms`)
- })
-
- await test('Average time to create 1 BLAKE2b account 0x20 times', async () => {
- const times = []
- const wallet = await Blake2bWallet.create(NANO_TEST_VECTORS.PASSWORD)
- await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)
- for (let i = 0; i < 0x20; i++) {
- const start = performance.now()
- await wallet.accounts(i)
- const end = performance.now()
- times.push(end - start)
- }
- const { total, arithmetic, harmonic, geometric } = average(times)
- console.log(`Total: ${total} ms`)
- console.log(`Average: ${arithmetic} ms`)
- console.log(`Harmonic: ${harmonic} ms`)
- console.log(`Geometric: ${geometric} ms`)
- })
-})
+++ /dev/null
-// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-'use strict'
-
-import { assert, average, skip, suite, test } from '#GLOBALS.mjs'
-import { NANO_TEST_VECTORS } from '#test/TEST_VECTORS.js'
-import { SendBlock } from '#dist/main.js'
-import 'nano-webgl-pow'
-
-await suite('Block performance', async () => {
- const COUNT = 0x10
-
- await test(`Customized PoW: Time to calculate proof-of-work for a send block ${COUNT} times`, async () => {
- const times = []
- const block = new SendBlock(
- NANO_TEST_VECTORS.SEND_BLOCK.account,
- NANO_TEST_VECTORS.SEND_BLOCK.balance,
- NANO_TEST_VECTORS.SEND_BLOCK.link,
- '0',
- NANO_TEST_VECTORS.SEND_BLOCK.representative,
- NANO_TEST_VECTORS.SEND_BLOCK.previous
- )
- for (let i = 0; i < COUNT; i++) {
- const start = performance.now()
- await block.pow()
- const end = performance.now()
- times.push(end - start)
- console.log(`${block.work} (${end - start} ms)`)
- }
- const { total, arithmetic, harmonic, geometric } = average(times)
- console.log(`Total: ${total} ms`)
- console.log(`Average: ${arithmetic} ms`)
- console.log(`Harmonic: ${harmonic} ms`)
- console.log(`Geometric: ${geometric} ms`)
- })
-
- await test(`Original PoW module: Time to calculate proof-of-work for a send block ${COUNT} times`, async () => {
- const times = []
- for (let i = 0; i < COUNT; i++) {
- const start = performance.now()
- const work = await new Promise(resolve => {
- //@ts-expect-error
- window.NanoWebglPow(NANO_TEST_VECTORS.SEND_BLOCK.previous, resolve, undefined, '0xFFFFFFF8')
- })
- const end = performance.now()
- times.push(end - start)
- console.log(`${work} (${end - start} ms)`)
- }
- const { total, arithmetic, harmonic, geometric } = average(times)
- console.log(`Total: ${total} ms`)
- console.log(`Average: ${arithmetic} ms`)
- console.log(`Harmonic: ${harmonic} ms`)
- console.log(`Geometric: ${geometric} ms`)
- })
-})
+++ /dev/null
-<!DOCTYPE html>
-
-<head>
- <link rel="icon" href="./favicon.ico">
- <script type="module" src="./dist/perf.min.js"></script>
- <style>body{background:black;}</style>
-</head>
-
-<body></body>
-
-</html>
+++ /dev/null
-// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-import * as main from './main.js'
-(globalThis as any).libnemo ??= main
// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>\r
// SPDX-License-Identifier: GPL-3.0-or-later\r
\r
-import { Blake2b } from './blake2b.js'\r
-import { ACCOUNT_KEY_LENGTH, ALPHABET, PREFIX, PREFIX_LEGACY } from './constants.js'\r
-import { base32, bytes, hex } from './convert.js'\r
-import { Rpc } from './rpc.js'\r
-import { Safe } from './safe.js'\r
-import { NanoNaCl } from './workers/nano-nacl.js'\r
+import { Blake2b } from './blake2b'\r
+import { ACCOUNT_KEY_LENGTH, ALPHABET, PREFIX, PREFIX_LEGACY } from './constants'\r
+import { base32, bytes, hex } from './convert'\r
+import { Rpc } from './rpc'\r
+import { Safe } from './safe'\r
+import { NanoNaCl } from '#workers'\r
\r
/**\r
* Represents a single Nano address and the associated public key. To include the\r
Account.#isInternal = false\r
}\r
\r
+ /**\r
+ * Removes encrypted secrets in storage and releases variable references to\r
+ * allow garbage collection.\r
+ */\r
+ destroy (): void {\r
+ this.#s.destroy(this.#pub)\r
+ this.#prv = null\r
+ this.#i = undefined\r
+ this.#f = undefined\r
+ this.#b = undefined\r
+ this.#r = undefined\r
+ this.#rep = undefined\r
+ this.#w = undefined\r
+ }\r
+\r
/**\r
* Instantiates an Account object from its Nano address.\r
*\r
return account\r
}\r
\r
- /**\r
- * Instantiates an Account object from its public and private\r
- * keys.\r
- *\r
- * WARNING: The validity of the keys is checked, but they are assumed to have\r
- * been precalculated. Whether they are an actual matching pair is NOT checked!\r
- * If unsure, use `Account.fromPrivateKey(key)` instead.\r
- *\r
- * @param {string} publicKey - Public key of the account\r
- * @param {string} privateKey - Private key of the account\r
- * @param {number} [index] - Account number used when deriving the key\r
- * @returns {Account} The instantiated Account object\r
- */\r
- static fromKeypair (privateKey: string, publicKey: string, index?: number): Account {\r
- Account.#isInternal = true\r
- Account.#validateKey(privateKey)\r
- const account = Account.fromPublicKey(publicKey, index)\r
- account.#prv = privateKey.toUpperCase()\r
- return account\r
- }\r
-\r
async lock (password: string): Promise<boolean>\r
async lock (key: CryptoKey): Promise<boolean>\r
async lock (passkey: string | CryptoKey): Promise<boolean> {\r
throw new TypeError('RPC must be a valid node')\r
}\r
const data = {\r
- "account": this.address,\r
- "receivable": "true",\r
- "representative": "true",\r
- "weight": "true"\r
+ account: this.address,\r
+ receivable: true,\r
+ representative: true,\r
+ weight: true\r
}\r
const { balance, frontier, receivable, representative, weight } = await rpc.call('account_info', data)\r
if (frontier == null) {\r
}\r
}\r
}\r
+\r
+export class AccountList extends Object {\r
+ [index: number]: Account\r
+\r
+ get length (): number {\r
+ return Object.keys(this).length\r
+ }\r
+\r
+ *[Symbol.iterator] (): Iterator<Account> {\r
+ const indexes = Object.keys(this)\r
+ .map(key => parseInt(key))\r
+ .filter(index => Number.isFinite(index))\r
+ .sort((a, b) => a - b)\r
+ for (const i of indexes) {\r
+ yield this[i]\r
+ }\r
+ }\r
+\r
+ static {\r
+ Object.defineProperty(this, 'length', { enumerable: false })\r
+ }\r
+}\r
// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>\r
// SPDX-License-Identifier: GPL-3.0-or-later\r
\r
-import { Bip39Words } from './bip39-wordlist.js'\r
-import { bin, bytes, dec, utf8 } from './convert.js'\r
-import { BIP39_ITERATIONS } from './constants.js'\r
-import { Entropy } from './entropy.js'\r
+import { Bip39Words } from './bip39-wordlist'\r
+import { BIP39_ITERATIONS } from './constants'\r
+import { bin, bytes, dec, utf8 } from './convert'\r
+import { Entropy } from './entropy'\r
\r
const { subtle } = globalThis.crypto\r
\r
\r
constructor () {\r
if (!Bip39Mnemonic.#isInternal) {\r
- throw new Error(`Bip39Mnemonic cannot be instantiated directly. Use 'await Bip39Mnemonic.fromPhrase()' or 'await Bip39Mnemonic.fromEntropy() instead.`)\r
+ throw new Error(`Bip39Mnemonic must be created with async methods 'fromPhrase()' or 'fromEntropy().`)\r
}\r
Bip39Mnemonic.#isInternal = false\r
}\r
if (passphrase == null || typeof passphrase !== 'string') {\r
passphrase = ''\r
}\r
- passphrase = `mnemonic${passphrase.normalize('NFKD')}`\r
-\r
- const derivationAlgorithm: Pbkdf2Params = {\r
- name: 'PBKDF2',\r
- hash: 'SHA-512',\r
- salt: utf8.toBytes(passphrase),\r
- iterations: BIP39_ITERATIONS\r
- }\r
- const phraseKey = await subtle.importKey('raw', utf8.toBytes(this.phrase), 'PBKDF2', false, ['deriveBits', 'deriveKey'])\r
+ const keyData = utf8.toBytes(this.phrase)\r
+ const phraseKey = await subtle.importKey('raw', keyData, 'PBKDF2', false, ['deriveBits', 'deriveKey'])\r
const derivedKeyType: HmacImportParams = {\r
name: 'HMAC',\r
hash: 'SHA-512',\r
length: 512\r
}\r
- const isSeedKeyExtractable: boolean = true\r
- const seedKeyUsages: KeyUsage[] = ['sign']\r
\r
- const seedKey = await subtle.deriveKey(derivationAlgorithm, phraseKey, derivedKeyType, isSeedKeyExtractable, seedKeyUsages)\r
+ passphrase = `mnemonic${passphrase.normalize('NFKD')}`\r
+ const algorithm: Pbkdf2Params = {\r
+ name: 'PBKDF2',\r
+ hash: 'SHA-512',\r
+ salt: utf8.toBytes(passphrase),\r
+ iterations: BIP39_ITERATIONS\r
+ }\r
+ const seedKey = await subtle.deriveKey(algorithm, phraseKey, derivedKeyType, true, ['sign'])\r
const seedBuffer = await subtle.exportKey('raw', seedKey)\r
const seedBytes = new Uint8Array(seedBuffer)\r
const seed = bytes.toHex(seedBytes)\r
-// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
-// SPDX-License-Identifier: GPL-3.0-or-later
+// SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
+// SPDX-License-Identifier: GPL-3.0-or-later AND ISC
/**
* Implementation derived from blake2b@2.1.4. Copyright 2017 Emil Bay
* <github@tixz.dk> (https://github.com/emilbayes/blake2b). See LICENSES/ISC.txt
*
-* Modified to eliminate dependencies, port to TypeScript, and embed in web
-* workers.
+* Modified to use BigUint64 values, eliminate dependencies, port to TypeScript,
+* and embed in web workers.
*
* Original source commit: https://github.com/emilbayes/blake2b/blob/1f63e02e3f226642959506cdaa67c8819ff145cd/index.js
*/
+type UnknownNumber = number | unknown
+type UnknownUint8Array = Uint8Array | unknown
export class Blake2b {
- static BYTES_MIN: number = 1
- static BYTES_MAX: number = 64
- static KEYBYTES_MIN: number = 16
- static KEYBYTES_MAX: number = 64
- static SALTBYTES: number = 16
- static PERSONALBYTES: number = 16
-
- // Initialization Vector
- static BLAKE2B_IV32: Uint32Array = new Uint32Array([
- 0xF3BCC908, 0x6A09E667, 0x84CAA73B, 0xBB67AE85,
- 0xFE94F82B, 0x3C6EF372, 0x5F1D36F1, 0xA54FF53A,
- 0xADE682D1, 0x510E527F, 0x2B3E6C1F, 0x9B05688C,
- 0xFB41BD6B, 0x1F83D9AB, 0x137E2179, 0x5BE0CD19
- ])
-
- static SIGMA8: number[] = [
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3,
- 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4,
- 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8,
- 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13,
- 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9,
- 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11,
- 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10,
- 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5,
- 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3
- ]
-
- /**
- * These are offsets into a uint64 buffer.
- * Multiply them all by 2 to make them offsets into a uint32 buffer,
- * because this is Javascript and we don't have uint64s
- */
- static SIGMA82: Uint8Array = new Uint8Array(this.SIGMA8.map(x => x * 2))
-
- // reusable parameter_block
- static parameter_block: Uint8Array = new Uint8Array([
- 0, 0, 0, 0, // 0: outlen, keylen, fanout, depth
- 0, 0, 0, 0, // 4: leaf length, sequential mode
- 0, 0, 0, 0, // 8: node offset
- 0, 0, 0, 0, // 12: node offset
- 0, 0, 0, 0, // 16: node depth, inner length, rfu
- 0, 0, 0, 0, // 20: rfu
- 0, 0, 0, 0, // 24: rfu
- 0, 0, 0, 0, // 28: rfu
- 0, 0, 0, 0, // 32: salt
- 0, 0, 0, 0, // 36: salt
- 0, 0, 0, 0, // 40: salt
- 0, 0, 0, 0, // 44: salt
- 0, 0, 0, 0, // 48: personal
- 0, 0, 0, 0, // 52: personal
- 0, 0, 0, 0, // 56: personal
- 0, 0, 0, 0 // 60: personal
- ])
-
-
- static v: Uint32Array = new Uint32Array(32)
- static m: Uint32Array = new Uint32Array(32)
-
- /**
- * 64-bit unsigned addition
- * Sets v[a,a+1] += v[b,b+1]
- * v should be a Uint32Array
- */
- static ADD64AA (v: Uint32Array, a: number, b: number): void {
- var o0 = v[a] + v[b]
- var o1 = v[a + 1] + v[b + 1]
- if (o0 >= 0x100000000) {
- o1++
- }
- v[a] = o0
- v[a + 1] = o1
+ static get OUTBYTES_MIN (): 1 { return 1 }
+ static get OUTBYTES_MAX (): 64 { return 64 }
+ static get KEYBYTES_MIN (): 1 { return 1 }
+ static get KEYBYTES_MAX (): 64 { return 64 }
+ static get SALTBYTES (): 16 { return 16 }
+ static get PERSONALBYTES (): 16 { return 16 }
+ static get IV (): bigint[] {
+ return [
+ 0x6a09e667f3bcc908n,
+ 0xbb67ae8584caa73bn,
+ 0x3c6ef372fe94f82bn,
+ 0xa54ff53a5f1d36f1n,
+ 0x510e527fade682d1n,
+ 0x9b05688c2b3e6c1fn,
+ 0x1f83d9abfb41bd6bn,
+ 0x5be0cd19137e2179n
+ ]
+ }
+ static get SIGMA (): number[][] {
+ return [
+ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
+ [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3],
+ [11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4],
+ [7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8],
+ [9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13],
+ [2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9],
+ [12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11],
+ [13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10],
+ [6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5],
+ [10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0],
+ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
+ [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3]
+ ]
}
- /**
- * 64-bit unsigned addition
- * Sets v[a,a+1] += b
- * b0 is the low 32 bits of b, b1 represents the high 32 bits
- */
- static ADD64AC (v: Uint32Array, a: number, b0: number, b1: number): void {
- var o0 = v[a] + b0
- if (b0 < 0) {
- o0 += 0x100000000
- }
- var o1 = v[a + 1] + b1
- if (o0 >= 0x100000000) {
- o1++
+ static #toHex (buf: Uint8Array): string {
+ let str = ''
+ for (let i = 0; i < buf.length; i++) {
+ str += buf[i].toString(16).padStart(2, '0')
}
- v[a] = o0
- v[a + 1] = o1
+ return str
}
- // Little-endian byte access
- static B2B_GET32 (arr: Uint8Array, i: number): number {
- return (arr[i] ^
- (arr[i + 1] << 8) ^
- (arr[i + 2] << 16) ^
- (arr[i + 3] << 24))
+ #G (r: number, i: number, a: number, b: number, c: number, d: number): void {
+ this.#v[a] += this.#v[b] + this.#m[Blake2b.SIGMA[r][2 * i + 0]]
+ this.#v[d] ^= this.#v[a]
+ this.#v[d] = (this.#v[d] >> 32n) | (this.#v[d] << 32n)
+ this.#v[c] += this.#v[d]
+ this.#v[b] ^= this.#v[c]
+ this.#v[b] = (this.#v[b] >> 24n) | (this.#v[b] << 40n)
+ this.#v[a] += this.#v[b] + this.#m[Blake2b.SIGMA[r][2 * i + 1]]
+ this.#v[d] ^= this.#v[a]
+ this.#v[d] = (this.#v[d] >> 16n) | (this.#v[d] << 48n)
+ this.#v[c] += this.#v[d]
+ this.#v[b] ^= this.#v[c]
+ this.#v[b] = (this.#v[b] >> 63n) | (this.#v[b] << 1n)
}
- /**
- * G Mixing function
- * The ROTRs are inlined for speed
- */
- static B2B_G (a: number, b: number, c: number, d: number, ix: number, iy: number): void {
- var x0 = Blake2b.m[ix]
- var x1 = Blake2b.m[ix + 1]
- var y0 = Blake2b.m[iy]
- var y1 = Blake2b.m[iy + 1]
-
- Blake2b.ADD64AA(Blake2b.v, a, b) // v[a,a+1] += v[b,b+1] ... in JS we must store a uint64 as two uint32s
- Blake2b.ADD64AC(Blake2b.v, a, x0, x1) // v[a, a+1] += x ... x0 is the low 32 bits of x, x1 is the high 32 bits
-
- // v[d,d+1] = (v[d,d+1] xor v[a,a+1]) rotated to the right by 32 bits
- var xor0 = Blake2b.v[d] ^ Blake2b.v[a]
- var xor1 = Blake2b.v[d + 1] ^ Blake2b.v[a + 1]
- Blake2b.v[d] = xor1
- Blake2b.v[d + 1] = xor0
-
- Blake2b.ADD64AA(Blake2b.v, c, d)
-
- // v[b,b+1] = (v[b,b+1] xor v[c,c+1]) rotated right by 24 bits
- xor0 = Blake2b.v[b] ^ Blake2b.v[c]
- xor1 = Blake2b.v[b + 1] ^ Blake2b.v[c + 1]
- Blake2b.v[b] = (xor0 >>> 24) ^ (xor1 << 8)
- Blake2b.v[b + 1] = (xor1 >>> 24) ^ (xor0 << 8)
-
- Blake2b.ADD64AA(Blake2b.v, a, b)
- Blake2b.ADD64AC(Blake2b.v, a, y0, y1)
-
- // v[d,d+1] = (v[d,d+1] xor v[a,a+1]) rotated right by 16 bits
- xor0 = Blake2b.v[d] ^ Blake2b.v[a]
- xor1 = Blake2b.v[d + 1] ^ Blake2b.v[a + 1]
- Blake2b.v[d] = (xor0 >>> 16) ^ (xor1 << 16)
- Blake2b.v[d + 1] = (xor1 >>> 16) ^ (xor0 << 16)
-
- Blake2b.ADD64AA(Blake2b.v, c, d)
-
- // v[b,b+1] = (v[b,b+1] xor v[c,c+1]) rotated right by 63 bits
- xor0 = Blake2b.v[b] ^ Blake2b.v[c]
- xor1 = Blake2b.v[b + 1] ^ Blake2b.v[c + 1]
- Blake2b.v[b] = (xor1 >>> 31) ^ (xor0 << 1)
- Blake2b.v[b + 1] = (xor0 >>> 31) ^ (xor1 << 1)
+ #ROUND (r: number): void {
+ this.#G(r, 0, 0, 4, 8, 12)
+ this.#G(r, 1, 1, 5, 9, 13)
+ this.#G(r, 2, 2, 6, 10, 14)
+ this.#G(r, 3, 3, 7, 11, 15)
+ this.#G(r, 4, 0, 5, 10, 15)
+ this.#G(r, 5, 1, 6, 11, 12)
+ this.#G(r, 6, 2, 7, 8, 13)
+ this.#G(r, 7, 3, 4, 9, 14)
}
/**
- * Compression function. 'last' flag indicates last block.
- * Note we're representing 16 uint64s as 32 uint32s
+ * Compression function called during three phases: on keying (if applicable),
+ * each time the input buffer is filled, and when finalizing message block.
+ *
+ * @param {boolean} final - If true, invert bits of v[14]
*/
- static blake2bCompress (ctx: any, last: boolean): void {
- let i = 0
+ #blake2bCompress (final: boolean): void {
// init work variables
- for (i = 0; i < 16; i++) {
- Blake2b.v[i] = ctx.h[i]
- Blake2b.v[i + 16] = Blake2b.BLAKE2B_IV32[i]
+ for (let i = 0; i < 8; i++) {
+ this.#v[i] = this.#h[i]
+ this.#v[i + 8] = Blake2b.IV[i]
}
- // low 64 bits of offset
- Blake2b.v[24] = Blake2b.v[24] ^ ctx.t
- Blake2b.v[25] = Blake2b.v[25] ^ (ctx.t / 0x100000000)
- // high 64 bits not supported, offset may not be higher than 2**53-1
+ // lo 64 bits of counter
+ this.#v[12] ^= this.#t & ((1n << 64n) - 1n)
+
+ // hi 64 bits of counter
+ this.#v[13] ^= this.#t & ((1n << 128n) - (1n << 64n))
- // last block flag set ?
- if (last) {
- Blake2b.v[28] = ~Blake2b.v[28]
- Blake2b.v[29] = ~Blake2b.v[29]
+ // is last block flag set?
+ if (final) {
+ this.#v[14] = ~this.#v[14]
}
- // get little-endian words
- for (i = 0; i < 32; i++) {
- Blake2b.m[i] = Blake2b.B2B_GET32(ctx.b, 4 * i)
+ // copy input buffer to message block
+ const buf = new DataView(this.#b.buffer)
+ for (let i = 0; i < 16; i++) {
+ this.#m[i] = buf.getBigUint64(i * 8, true)
}
// twelve rounds of mixing
- for (i = 0; i < 12; i++) {
- Blake2b.B2B_G(0, 8, 16, 24, Blake2b.SIGMA82[i * 16 + 0], Blake2b.SIGMA82[i * 16 + 1])
- Blake2b.B2B_G(2, 10, 18, 26, Blake2b.SIGMA82[i * 16 + 2], Blake2b.SIGMA82[i * 16 + 3])
- Blake2b.B2B_G(4, 12, 20, 28, Blake2b.SIGMA82[i * 16 + 4], Blake2b.SIGMA82[i * 16 + 5])
- Blake2b.B2B_G(6, 14, 22, 30, Blake2b.SIGMA82[i * 16 + 6], Blake2b.SIGMA82[i * 16 + 7])
- Blake2b.B2B_G(0, 10, 20, 30, Blake2b.SIGMA82[i * 16 + 8], Blake2b.SIGMA82[i * 16 + 9])
- Blake2b.B2B_G(2, 12, 22, 24, Blake2b.SIGMA82[i * 16 + 10], Blake2b.SIGMA82[i * 16 + 11])
- Blake2b.B2B_G(4, 14, 16, 26, Blake2b.SIGMA82[i * 16 + 12], Blake2b.SIGMA82[i * 16 + 13])
- Blake2b.B2B_G(6, 8, 18, 28, Blake2b.SIGMA82[i * 16 + 14], Blake2b.SIGMA82[i * 16 + 15])
+ for (let i = 0; i < 12; i++) {
+ this.#ROUND(i)
}
- for (i = 0; i < 16; i++) {
- ctx.h[i] = ctx.h[i] ^ Blake2b.v[i] ^ Blake2b.v[i + 16]
+ // set new chain value
+ for (let i = 0; i < 8; i++) {
+ this.#h[i] ^= this.#v[i] ^ this.#v[i + 8]
}
}
/**
- * Updates a BLAKE2b streaming hash
- * Requires hash context and Uint8Array (byte array)
+ * Update the BLAKE2b streaming hash with additional input. When the 128-byte
+ * input buffer is full, compress and start refilling.
*/
- static blake2bUpdate (ctx: any, input: Uint8Array): void {
- for (var i = 0; i < input.length; i++) {
- if (ctx.c === 128) { // buffer full ?
- ctx.t += ctx.c // add counters
- Blake2b.blake2bCompress(ctx, false) // compress (not last)
- ctx.c = 0 // counter to zero
+ #blake2bUpdate (input: Uint8Array): void {
+ for (let i = 0; i < input.length; i++) {
+ if (this.#c === this.#b.byteLength) { // is buffer full?
+ this.#t += BigInt(this.#b.byteLength) // increment total byte counter
+ this.#c = 0 // reset buffer counter to zero
+ this.#blake2bCompress(false) // compress (not final)
}
- ctx.b[ctx.c++] = input[i]
+ this.#b[this.#c++] = input[i]
}
}
/**
- * Completes a BLAKE2b streaming hash
- * Returns a Uint8Array containing the message digest
+ * Completes a BLAKE2b streaming hash.
+ *
+ * @param {Uint8Array} out - Buffer to store the final output
*/
- static blake2bFinal (ctx: any, out: Uint8Array): Uint8Array {
- ctx.t += ctx.c // mark last block offset
-
- while (ctx.c < 128) { // fill up with zeros
- ctx.b[ctx.c++] = 0
- }
- Blake2b.blake2bCompress(ctx, true) // final block flag = 1
-
- for (var i = 0; i < ctx.outlen; i++) {
- out[i] = ctx.h[i >> 2] >> (8 * (i & 3))
+ #blake2bFinal (out: Uint8Array): void {
+ this.#t += BigInt(this.#c) // add final message block size to total bytes
+ this.#b.fill(0, this.#c) // pad final block with zeros
+ this.#blake2bCompress(true) // set final block flag and compress
+ const data = new DataView(this.#h.buffer)
+ for (let i = 0; i < this.#outlen; i++) {
+ out[i] = data.getUint8(i)
}
- return out
- }
-
- static hexSlice (buf: Uint8Array): string {
- let str = ''
- for (let i = 0; i < buf.length; i++) str += Blake2b.toHex(buf[i])
- return str
}
- static toHex (n: number): string {
- if (typeof n !== 'number')
- throw new TypeError(`expected number to convert to hex; received ${typeof n}`)
- if (n < 0 || n > 255)
- throw new RangeError(`expected byte value 0-255; received ${n}`)
- return n.toString(16).padStart(2, '0')
- }
-
- b: Uint8Array
- h: Uint32Array
- t: number
- c: number
- outlen: number
+ #parameter_block: Uint8Array = new Uint8Array([
+ 0, 0, 0, 0, // 0: outlen, keylen, fanout, depth
+ 0, 0, 0, 0, // 4: leaf length (0 for sequential mode)
+ 0, 0, 0, 0, // 8: node offset
+ 0, 0, 0, 0, // 12: node offset
+ 0, 0, 0, 0, // 16: node depth, inner length, rfu
+ 0, 0, 0, 0, // 20: rfu
+ 0, 0, 0, 0, // 24: rfu
+ 0, 0, 0, 0, // 28: rfu
+ 0, 0, 0, 0, // 32: salt
+ 0, 0, 0, 0, // 36: salt
+ 0, 0, 0, 0, // 40: salt
+ 0, 0, 0, 0, // 44: salt
+ 0, 0, 0, 0, // 48: personal
+ 0, 0, 0, 0, // 52: personal
+ 0, 0, 0, 0, // 56: personal
+ 0, 0, 0, 0 // 60: personal
+ ])
+ #parameter_view: DataView = new DataView(this.#parameter_block.buffer)
+ /** Byte buffer which is compressed when full */
+ #b: Uint8Array = new Uint8Array(128)
+ /** Hash chain value */
+ #h: BigUint64Array = new BigUint64Array(8)
+ /** Total input byte count (BLAKE2b supports 2¹²⁸-1) */
+ #t: bigint = 0n
+ /** Pointer to current element within input buffer */
+ #c: number = 0
+ /** State vector */
+ #v: BigUint64Array = new BigUint64Array(16)
+ /** Message block */
+ #m: BigUint64Array = new BigUint64Array(16)
+ /** User-requested output length */
+ #outlen: number
/**
- * Creates a BLAKE2b hashing context
- * Requires an output length between 1 and 64 bytes
- * Takes an optional Uint8Array key
+ * Creates a BLAKE2b hashing context.
+ *
+ * @param {number} length - Output length between 1-64 bytes
+ * @param {Uint8Array} [key] - (_optional_) Used for keyed hashing (MAC and PRF)
+ * @param {Uint8Array} [salt] - (_optional_) Used to simplify randomized hashing for digital signatures
+ * @param {Uint8Array} [personal] - (_optional_) Arbitrary user-specified value
*/
- constructor (outlen: number, key?: Uint8Array, salt?: Uint8Array, personal?: Uint8Array, noAssert?: boolean) {
- if (noAssert !== true) {
- if (outlen < Blake2b.BYTES_MIN) throw new RangeError(`expected outlen >= ${Blake2b.BYTES_MIN}; actual ${outlen}`)
- if (outlen > Blake2b.BYTES_MAX) throw new RangeError(`expectd outlen <= ${Blake2b.BYTES_MAX}; actual ${outlen}`)
- if (key != null) {
- if (!(key instanceof Uint8Array)) throw new TypeError(`key must be Uint8Array or Buffer`)
- if (key.length < Blake2b.KEYBYTES_MIN) throw new RangeError(`expected key >= ${Blake2b.KEYBYTES_MIN}; actual ${key.length}`)
- if (key.length > Blake2b.KEYBYTES_MAX) throw new RangeError(`expected key <= ${Blake2b.KEYBYTES_MAX}; actual ${key.length}`)
+ constructor (length: UnknownNumber, key?: UnknownUint8Array, salt?: UnknownUint8Array, personal?: UnknownUint8Array) {
+ if (length == null) {
+ throw new TypeError(`length is required`)
+ }
+ if (typeof length !== 'number') {
+ throw new TypeError(`length must be number`)
+ }
+ if (length < Blake2b.OUTBYTES_MIN || length > Blake2b.OUTBYTES_MAX) {
+ throw new RangeError(`length must be ${Blake2b.OUTBYTES_MIN}-${Blake2b.OUTBYTES_MAX} bytes`)
+ }
+ if (key != null) {
+ if (!(key instanceof Uint8Array)) {
+ throw new TypeError(`key must be Uint8Array or Buffer`)
+ }
+ if (key.length < Blake2b.KEYBYTES_MIN || key.length > Blake2b.KEYBYTES_MAX) {
+ throw new RangeError(`key must be ${Blake2b.KEYBYTES_MIN}-${Blake2b.KEYBYTES_MAX} bytes`)
+ }
+ }
+ if (salt != null) {
+ if (!(salt instanceof Uint8Array)) {
+ throw new TypeError(`salt must be Uint8Array or Buffer`)
+ }
+ if (salt.length !== Blake2b.SALTBYTES) {
+ throw new RangeError(`salt must be ${Blake2b.SALTBYTES} bytes`)
}
- if (salt != null) {
- if (!(salt instanceof Uint8Array)) throw new TypeError(`salt must be Uint8Array or Buffer`)
- if (salt.length !== Blake2b.SALTBYTES) throw new RangeError(`expected salt ${Blake2b.SALTBYTES} bytes; actual ${salt.length} bytes`)
+ }
+ if (personal != null) {
+ if (!(personal instanceof Uint8Array)) {
+ throw new TypeError(`personal must be Uint8Array or Buffer`)
}
- if (personal != null) {
- if (!(personal instanceof Uint8Array)) throw new TypeError(`personal must be Uint8Array or Buffer`)
- if (personal.length !== Blake2b.PERSONALBYTES) throw new RangeError(`expected personal ${Blake2b.PERSONALBYTES} bytes; actual ${personal.length} bytes`)
+ if (personal.length !== Blake2b.PERSONALBYTES) {
+ throw new RangeError(`personal must be ${Blake2b.PERSONALBYTES} bytes`)
}
}
- this.b = new Uint8Array(128)
- this.h = new Uint32Array(16)
- this.t = 0 // input count
- this.c = 0 // pointer within buffer
- this.outlen = outlen // output length in bytes
+ this.#outlen = length // output length in bytes
- // zero out parameter_block before usage
- Blake2b.parameter_block.fill(0)
// state, 'param block'
+ this.#parameter_block[0] = length
+ this.#parameter_block[1] = key?.length ?? 0
+ this.#parameter_block[2] = 1 // fanout
+ this.#parameter_block[3] = 1 // depth
- Blake2b.parameter_block[0] = outlen
- if (key) Blake2b.parameter_block[1] = key.length
- Blake2b.parameter_block[2] = 1 // fanout
- Blake2b.parameter_block[3] = 1 // depth
-
- if (salt) Blake2b.parameter_block.set(salt, 32)
- if (personal) Blake2b.parameter_block.set(personal, 48)
+ if (salt) this.#parameter_block.set(salt, 32)
+ if (personal) this.#parameter_block.set(personal, 48)
// initialize hash state
- for (var i = 0; i < 16; i++) {
- this.h[i] = Blake2b.BLAKE2B_IV32[i] ^ Blake2b.B2B_GET32(Blake2b.parameter_block, i * 4)
+ for (let i = 0; i < 8; i++) {
+ this.#h[i] = Blake2b.IV[i] ^ this.#parameter_view.getBigUint64(i * 8, true)
}
// key the hash, if applicable
if (key) {
- Blake2b.blake2bUpdate(this, key)
- // at the end
- this.c = 128
+ this.#blake2bUpdate(key)
+ // force input buffer to reset for first block of actual message
+ this.#c = 128
}
}
update (input: Uint8Array): Blake2b {
- if (!(input instanceof Uint8Array))
+ if (!(input instanceof Uint8Array)) {
throw new TypeError(`input must be Uint8Array or Buffer`)
- Blake2b.blake2bUpdate(this, input)
+ }
+ this.#blake2bUpdate(input)
return this
}
digest (out: 'hex'): string
digest (out: 'binary' | Uint8Array): Uint8Array
digest (out?: 'binary' | 'hex' | Uint8Array): string | Uint8Array {
- const buf = (!out || out === 'binary' || out === 'hex') ? new Uint8Array(this.outlen) : out
+ const buf = (!out || out === 'binary' || out === 'hex') ? new Uint8Array(this.#outlen) : out
if (!(buf instanceof Uint8Array)) throw new TypeError(`out must be "binary", "hex", Uint8Array, or Buffer`)
- if (buf.length < this.outlen) throw new RangeError(`out must have at least outlen bytes of space`)
- Blake2b.blake2bFinal(this, buf)
- if (out === 'hex') return Blake2b.hexSlice(buf) as string
- return buf
+ if (buf.length < this.#outlen) throw new RangeError(`out must have at least outlen bytes of space`)
+ this.#blake2bFinal(buf)
+ return (out === 'hex')
+ ? Blake2b.#toHex(buf)
+ : buf
}
}
// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
// SPDX-License-Identifier: GPL-3.0-or-later
-import { BURN_ADDRESS, PREAMBLE, THRESHOLD_RECEIVE, THRESHOLD_SEND } from './constants.js'
-import { Account } from './account.js'
-import { Blake2b } from './blake2b.js'
-import { dec, hex } from './convert.js'
-import { NanoNaCl } from './workers/nano-nacl.js'
-import { Pool } from './pool.js'
-import { Rpc } from './rpc.js'
-import { Pow } from './workers.js'
+import { NanoPow } from 'nano-pow'
+import { Account } from './account'
+import { Blake2b } from './blake2b'
+import { BURN_ADDRESS, PREAMBLE, DIFFICULTY_RECEIVE, DIFFICULTY_SEND } from './constants'
+import { dec, hex } from './convert'
+import { Pool } from './pool'
+import { Rpc } from './rpc'
+import { NanoNaCl, NanoNaClWorker } from '#workers'
/**
* Represents a block as defined by the Nano cryptocurrency protocol. The Block
* of three derived classes: SendBlock, ReceiveBlock, ChangeBlock.
*/
abstract class Block {
- static #pool: Pool = new Pool(Pow)
+ static #pool: Pool
account: Account
type: string = 'state'
abstract subtype: 'send' | 'receive' | 'change'
} else {
throw new TypeError('Invalid account')
}
+ Block.#pool ??= new Pool(NanoNaClWorker)
}
/**
- * Converts the block to JSON format as expected by the `process` RPC.
- *
- * @returns {string} JSON representation of the block
- */
- json (): { [key: string]: string } {
- return {
- "type": this.type,
- "account": this.account.address,
- "previous": this.previous,
- "representative": this.representative.address,
- "balance": this.balance.toString(),
- "link": this.link,
- "signature": this.signature ?? '',
- "work": this.work ?? ''
- }
- }
-
- /**
- * Hashes the block using Blake2b.
+ * Calculates the block hash using Blake2b.
*
* @returns {Promise<string>} Block data hashed to a byte array
*/
- async hash (): Promise<string> {
+ get hash (): string {
const data = [
PREAMBLE,
this.account.publicKey,
}
/**
- * Calculates proof-of-work using a pool of WebGL workers.
+ * Converts the block to JSON format as expected by the `process` RPC.
+ *
+ * @returns {string} JSON representation of the block
+ */
+ toJSON (): { [key: string]: string } {
+ return {
+ "type": this.type,
+ "account": this.account.address,
+ "previous": this.previous,
+ "representative": this.representative.address,
+ "balance": this.balance.toString(),
+ "link": this.link,
+ "signature": this.signature ?? '',
+ "work": this.work ?? ''
+ }
+ }
+
+ /**
+ * Calculates proof-of-work using a pool of Web Workers.
*
* A successful response sets the `work` property.
*/
async pow (): Promise<void> {
- const data = {
- "hash": this.previous,
- "threshold": (this instanceof SendBlock || this instanceof ChangeBlock)
- ? THRESHOLD_SEND
- : THRESHOLD_RECEIVE
+ const difficulty: bigint = (this instanceof SendBlock || this instanceof ChangeBlock)
+ ? DIFFICULTY_SEND
+ : DIFFICULTY_RECEIVE
+ const result = await NanoPow.work_generate(this.previous, { difficulty })
+ if ('error' in result) {
+ throw new Error('Failed to generate work', { cause: result.error })
}
- const [{ work }] = await Block.#pool.assign([data])
- this.work = work
+ this.work = result.work
}
/**
async sign (input?: number | string, block?: { [key: string]: string }): Promise<void> {
if (typeof input === 'number') {
const index = input
- const { Ledger } = await import('./ledger.js')
+ const { Ledger } = await import('./ledger')
const ledger = await Ledger.init()
await ledger.open()
if (block) {
}
}
const result = await ledger.sign(index, this as SendBlock | ReceiveBlock | ChangeBlock)
- if (result.status !== 'OK') {
+ if (result.status !== 'OK' || result.signature == null) {
throw new Error(result.status)
}
this.signature = result.signature
}
const account = await Account.fromPrivateKey(key)
try {
- const signature = NanoNaCl.detached(
- hex.toBytes(await this.hash()),
- hex.toBytes(`${account.privateKey}`)
- )
- this.signature = signature
+ const result = (await Block.#pool.assign({
+ method: 'detached',
+ msg: hex.toArray(this.hash),
+ secretKey: hex.toArray(`${account.privateKey}`)
+ }))[0]
+ this.signature = result.signature
} catch (err) {
- throw new Error(`Failed to sign block with key ${key}: ${err}`)
+ throw new Error(`Failed to sign block`, { cause: err })
}
}
}
const data = {
"subtype": this.subtype,
"json_block": "true",
- "block": this.json()
+ "block": this.toJSON()
}
const res = await rpc.call('process', data)
if (res.hash == null) {
if (!key) {
throw new Error('Provide a key for block signature verification.')
}
- const data = [
- PREAMBLE,
- this.account.publicKey,
- this.previous,
- this.representative.publicKey,
- dec.toHex(this.balance, 32),
- this.link
- ]
- const hash = new Blake2b(32)
- data.forEach(str => hash.update(hex.toBytes(str)))
- const blockHash = hash.digest('hex').toUpperCase()
return NanoNaCl.verify(
- hex.toBytes(blockHash),
+ hex.toBytes(this.hash),
hex.toBytes(this.signature ?? ''),
hex.toBytes(key)
)
signature?: string
work?: string
- constructor (sender: Account | string, balance: string, recipient: string, amount: string, representative: string, frontier: string, work?: string) {
+ constructor (
+ sender: Account | string,
+ balance: string,
+ recipient: string,
+ amount: string,
+ representative: Account | string,
+ frontier: string,
+ work?: string
+ ) {
+ if (typeof sender === 'string') sender = Account.fromAddress(sender)
+ if (typeof representative === 'string') representative = Account.fromAddress(representative)
super(sender)
this.previous = frontier
- this.representative = Account.fromAddress(representative)
+ this.representative = representative
this.link = Account.fromAddress(recipient).publicKey
this.work = work ?? ''
signature?: string
work?: string
- constructor (recipient: string, balance: string, origin: string, amount: string, representative: string, frontier?: string, work?: string) {
+ constructor (
+ recipient: Account | string,
+ balance: string,
+ origin: string,
+ amount: string,
+ representative: Account | string,
+ frontier?: string,
+ work?: string
+ ) {
+ if (typeof recipient === 'string') recipient = Account.fromAddress(recipient)
+ if (typeof representative === 'string') representative = Account.fromAddress(representative)
super(recipient)
- this.previous = frontier ?? Account.fromAddress(recipient).publicKey
- this.representative = Account.fromAddress(representative)
+ this.previous = frontier ?? recipient.publicKey
+ this.representative = representative
this.link = origin
this.work = work ?? ''
signature?: string
work?: string
- constructor (account: string, balance: string, representative: string, frontier: string, work?: string) {
+ constructor (
+ account: Account | string,
+ balance: string,
+ representative: Account | string,
+ frontier: string,
+ work?: string
+ ) {
+ if (typeof account === 'string') account = Account.fromAddress(account)
+ if (typeof representative === 'string') representative = Account.fromAddress(representative)
super(account)
this.previous = frontier
- this.representative = Account.fromAddress(representative)
+ this.representative = representative
this.balance = BigInt(balance)
this.work = work ?? ''
export const SEED_LENGTH_BIP44 = 128
export const SEED_LENGTH_BLAKE2B = 64
export const SLIP10_ED25519 = 'ed25519 seed'
-export const THRESHOLD_RECEIVE = 0xfffffe00
-export const THRESHOLD_SEND = 0xfffffff8
+export const DIFFICULTY_RECEIVE = 0xfffffe0000000000n
+export const DIFFICULTY_SEND = 0xfffffff800000000n
export const XNO = 'Ӿ'
export const LEDGER_STATUS_CODES: { [key: number]: string } = Object.freeze({
// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>\r
// SPDX-License-Identifier: GPL-3.0-or-later\r
\r
-import { ALPHABET } from "./constants.js"\r
+import { ALPHABET } from './constants'\r
+\r
+const encoder = new TextEncoder()\r
+const decoder = new TextDecoder()\r
\r
export const base32 = {\r
/**\r
* @param {string} bin - String to convert\r
* @returns {Uint8Array} Byte array representation of the input string\r
*/\r
- toBytes (bin: string): Uint8Array {\r
+ toBytes (bin: string): Uint8Array<ArrayBuffer> {\r
const bytes: number[] = []\r
while (bin.length > 0) {\r
const bits = bin.substring(0, 8)\r
* @returns {string} UTF-8 encoded text string\r
*/\r
toUtf8 (bytes: Uint8Array): string {\r
- return new TextDecoder().decode(bytes)\r
+ return decoder.decode(bytes)\r
}\r
}\r
\r
* Convert a decimal integer to a binary string.\r
*\r
* @param {bigint|number|string} decimal - Integer to convert\r
- * @param {number} [padding=0] - Minimum length of the resulting string which will be padded as necessary with starting zeroes\r
+ * @param {number} [padding=0] - Minimum length of the resulting string padded as necessary with starting zeroes\r
* @returns {string} Binary string representation of the input decimal\r
*/\r
toBin (decimal: bigint | number | string, padding: number = 0): string {\r
* Convert a decimal integer to a Uint8Array of bytes. Fractional part is truncated.\r
*\r
* @param {bigint|number|string} decimal - Integer to convert\r
- * @param {number} [padding=0] - Minimum length of the resulting array which will be padded as necessary with starting 0x00 bytes\r
+ * @param {number} [padding=0] - Minimum length of the resulting array padded as necessary with starting 0x00 bytes\r
* @returns {Uint8Array} Byte array representation of the input decimal\r
*/\r
toBytes (decimal: bigint | number | string, padding: number = 0): Uint8Array {\r
* Convert a decimal integer to a hexadecimal string.\r
*\r
* @param {(bigint|number|string)} decimal - Integer to convert\r
- * @param {number} [padding=0] - Minimum length of the resulting string which will be padded as necessary with starting zeroes\r
+ * @param {number} [padding=0] - Minimum length of the resulting string padded as necessary with starting zeroes\r
* @returns {string} Hexadecimal string representation of the input decimal\r
*/\r
toHex (decimal: bigint | number | string, padding: number = 0): string {\r
}\r
\r
export const hex = {\r
+ /**\r
+ * Convert a hexadecimal string to an array of decimal byte values.\r
+ *\r
+ * @param {string} hex - Hexadecimal number string to convert\r
+ * @param {number}[padding=0] - Minimum length of the resulting array padded as necessary with starting 0 values\r
+ * @returns {number[]} Decimal array representation of the input value\r
+ */\r
+ toArray (hex: string, padding: number = 0): number[] {\r
+ if (typeof hex !== 'string' || !/^[A-Fa-f0-9]+$/i.test(hex)) {\r
+ throw new TypeError('Invalid string when converting hex to array')\r
+ }\r
+ if (typeof padding !== 'number') {\r
+ throw new TypeError('Invalid padding when converting hex to array')\r
+ }\r
+ if (hex.length % 2 === 1) hex = `0${hex}`\r
+ const hexArray = hex.match(/.{2}/g)\r
+ if (hexArray == null) {\r
+ throw new RangeError('Invalid hex string when converting to array')\r
+ }\r
+ for (let i = hexArray.length; i < padding; i++) {\r
+ hexArray.unshift('0')\r
+ }\r
+ return hexArray.map(v => parseInt(v, 16))\r
+ },\r
/**\r
* Convert a hexadecimal string to a binary string.\r
*\r
* Convert a hexadecimal string to a Uint8Array of bytes.\r
*\r
* @param {string} hex - Hexadecimal number string to convert\r
- * @param {number} [padding=0] - Minimum length of the resulting array which will be padded as necessary with starting 0x00 bytes\r
+ * @param {number} [padding=0] - Minimum length of the resulting array padded as necessary with starting 0x00 bytes\r
* @returns {Uint8Array} Byte array representation of the input value\r
*/\r
- toBytes (hex: string, padding: number = 0): Uint8Array {\r
- if (typeof padding !== 'number') {\r
- throw new TypeError('Invalid padding when converting hex to bytes')\r
- }\r
- const hexArray = hex.match(/.{1,2}/g)\r
- if (!/^[0-9a-f]+$/i.test(hex) || hexArray == null) {\r
- console.warn('Invalid hex string when converting to bytes')\r
- return new Uint8Array()\r
- } else {\r
- const bytes = Uint8Array.from(hexArray.map(byte => parseInt(byte, 16)))\r
- const result = new Uint8Array(Math.max(padding, bytes.length))\r
- result.set(bytes.reverse())\r
- return result.reverse()\r
- }\r
+ toBytes (hex: string, padding: number = 0): Uint8Array<ArrayBuffer> {\r
+ return new Uint8Array(this.toArray(hex, padding))\r
}\r
}\r
\r
* @returns {Uint8Array} Byte array representation of the input string\r
*/\r
toBytes (utf8: string): Uint8Array {\r
- return new TextEncoder().encode(utf8)\r
+ return encoder.encode(utf8)\r
},\r
/**\r
* Convert a string to a hexadecimal representation\r
// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
// SPDX-License-Identifier: GPL-3.0-or-later
-import { bytes, hex } from './convert.js'
+import { bytes, hex } from './convert'
const { crypto } = globalThis
const MIN = 16
*/
export class Entropy {
static #isInternal: boolean = false
- #bytes: Uint8Array
+ #bytes: Uint8Array<ArrayBuffer>
get bits (): string { return bytes.toBin(this.#bytes) }
get buffer (): ArrayBuffer { return this.#bytes.buffer }
get bytes (): Uint8Array { return this.#bytes }
get hex (): string { return bytes.toHex(this.#bytes) }
- constructor (bytes: Uint8Array) {
+ constructor (bytes: Uint8Array<ArrayBuffer>) {
if (!Entropy.#isInternal) {
throw new Error(`Entropy cannot be instantiated directly. Use 'await Entropy.create()' instead.`)
}
* Import existing entropy and validate it.
* @param {Uint8Array} bytes - Byte array
*/
- static async import (bytes: Uint8Array): Promise<Entropy>
- static async import (input: string | ArrayBuffer | Uint8Array): Promise<Entropy> {
+ static async import (bytes: Uint8Array<ArrayBuffer>): Promise<Entropy>
+ static async import (input: string | ArrayBuffer | Uint8Array<ArrayBuffer>): Promise<Entropy> {
return new Promise((resolve, reject) => {
if (typeof input === 'string') {
if (input.length < MIN * 2 || input.length > MAX * 2) {
}
if (input instanceof Uint8Array) {
+ if (!(input.buffer instanceof ArrayBuffer)) {
+ throw new TypeError(`Entropy imported bytes must be backed by an ArrayBuffer.`)
+ }
if (input.length < MIN || input.length > MAX) {
throw new Error(`Entropy must be ${MIN}-${MAX} bytes`)
}
// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
// SPDX-License-Identifier: GPL-3.0-or-later
-/**
-* Ledger ADPU commands: https://github.com/roosmaa/ledger-app-nano/blob/master/doc/nano.md
-*/
+// Ledger ADPU commands: https://github.com/roosmaa/ledger-app-nano/blob/master/doc/nano.md
import Transport from '@ledgerhq/hw-transport'
import { default as TransportBLE } from '@ledgerhq/hw-transport-web-ble'
import { default as TransportUSB } from '@ledgerhq/hw-transport-webusb'
import { default as TransportHID } from '@ledgerhq/hw-transport-webhid'
-import { BIP44_COIN_NANO, BIP44_PURPOSE, HARDENED_OFFSET, LEDGER_STATUS_CODES } from './constants.js'
-import { bytes, dec, hex, utf8 } from './convert.js'
-import { Rpc } from './rpc.js'
-import { ChangeBlock, ReceiveBlock, SendBlock } from './block.js'
+import { ChangeBlock, ReceiveBlock, SendBlock } from './block'
+import { BIP44_COIN_NANO, BIP44_PURPOSE, HARDENED_OFFSET, LEDGER_STATUS_CODES } from './constants'
+import { bytes, dec, hex, utf8 } from './convert'
+import { Rpc } from './rpc'
+
+interface LedgerResponse {
+ status: string
+}
+
+interface LedgerVersionResponse extends LedgerResponse {
+ name: string | null,
+ version: string | null
+}
+
+interface LedgerAccountResponse extends LedgerResponse {
+ publicKey: string | null,
+ address: string | null
+}
+
+interface LedgerSignResponse extends LedgerResponse {
+ signature: string | null,
+ hash?: string
+}
export class Ledger {
static #isInternal: boolean = false
+ static #adpu = {
+ class: 0xa1,
+ bip32DerivationLevel: 0x03,
+ version: 0x01,
+ account: 0x02,
+ cacheBlock: 0x03,
+ signBlock: 0x04,
+ signNonce: 0x05,
+ paramUnused: 0x00
+ }
#status: 'DISCONNECTED' | 'LOCKED' | 'BUSY' | 'CONNECTED' = 'DISCONNECTED'
get status () { return this.#status }
openTimeout = 3000
return this.status
}
- async onDisconnectUsb (e: USBConnectionEvent) {
+ async onDisconnectUsb (e: USBConnectionEvent): Promise<void> {
if (e.device?.manufacturerName === 'Ledger') {
const { usb } = globalThis.navigator
usb.removeEventListener('disconnect', this.onDisconnectUsb)
*
* @returns Status of command
*/
- async open (): Promise<{ status: string }> {
+ async open (): Promise<LedgerResponse> {
const name = new TextEncoder().encode('Nano')
const transport = await this.DynamicTransport.create(this.openTimeout, this.listenTimeout)
- const response = await transport.send(0xe0, 0xd8, 0x00, 0x00, name as Buffer)
+ const response = await transport.send(0xe0, 0xd8, Ledger.#adpu.paramUnused, Ledger.#adpu.paramUnused, name as Buffer)
.then(res => bytes.toDec(res))
.catch(err => err.statusCode) as number
return new Promise(resolve => setTimeout(resolve, 1000, { status: LEDGER_STATUS_CODES[response] }))
*
* @returns Status of command
*/
- async close (): Promise<string> {
+ async close (): Promise<LedgerResponse> {
const transport = await this.DynamicTransport.create(this.openTimeout, this.listenTimeout)
- const response = await transport.send(0xb0, 0xa7, 0x00, 0x00)
+ const response = await transport.send(0xb0, 0xa7, Ledger.#adpu.paramUnused, Ledger.#adpu.paramUnused)
.then(res => bytes.toDec(res))
.catch(err => err.statusCode) as number
return new Promise(resolve => setTimeout(resolve, 1000, { status: LEDGER_STATUS_CODES[response] }))
*
* @returns Status, process name, and version
*/
- async version (): Promise<{ status: string, name: string | null, version: string | null }> {
+ async version (): Promise<LedgerVersionResponse> {
const transport = await this.DynamicTransport.create(this.openTimeout, this.listenTimeout)
- const response = await transport.send(0xb0, 0x01, 0x00, 0x00)
+ const response = await transport.send(0xb0, Ledger.#adpu.version, Ledger.#adpu.paramUnused, Ledger.#adpu.paramUnused)
.catch(err => dec.toBytes(err.statusCode)) as Uint8Array
await transport.close()
*
* @returns Response object containing command status, public key, and address
*/
- async account (index: number = 0, show: boolean = false): Promise<{ status: string, publicKey: string | null, address: string | null }> {
+ async account (index: number = 0, show: boolean = false): Promise<LedgerAccountResponse> {
if (typeof index !== 'number' || index < 0 || index >= HARDENED_OFFSET) {
throw new TypeError('Invalid account index')
}
const purpose = dec.toBytes(BIP44_PURPOSE + HARDENED_OFFSET, 4)
const coin = dec.toBytes(BIP44_COIN_NANO + HARDENED_OFFSET, 4)
const account = dec.toBytes(index + HARDENED_OFFSET, 4)
- const data = new Uint8Array([0x03, ...purpose, ...coin, ...account])
+ const data = new Uint8Array([Ledger.#adpu.bip32DerivationLevel, ...purpose, ...coin, ...account])
const transport = await this.DynamicTransport.create(this.openTimeout, this.listenTimeout)
- const response = await transport.send(0xa1, 0x02, show ? 0x01 : 0x00, 0x00, data as Buffer)
+ const response = await transport.send(Ledger.#adpu.class, Ledger.#adpu.account, show ? 0x01 : 0x00, Ledger.#adpu.paramUnused, data as Buffer)
.catch(err => dec.toBytes(err.statusCode)) as Uint8Array
await transport.close()
* @param {any} block - Block data to cache
* @returns Status of command
*/
- async cacheBlock (index: number = 0, block: SendBlock | ReceiveBlock | ChangeBlock): Promise<{ status: string }> {
+ async cacheBlock (index: number = 0, block: SendBlock | ReceiveBlock | ChangeBlock): Promise<LedgerResponse> {
if (typeof index !== 'number' || index < 0 || index >= HARDENED_OFFSET) {
throw new TypeError('Invalid account index')
}
const representative = hex.toBytes(block.representative.publicKey)
const balance = hex.toBytes(BigInt(block.balance).toString(16), 16)
const signature = hex.toBytes(block.signature)
- const data = new Uint8Array([0x03, ...purpose, ...coin, ...account, ...previous, ...link, ...representative, ...balance, ...signature])
+ const data = new Uint8Array([Ledger.#adpu.bip32DerivationLevel, ...purpose, ...coin, ...account, ...previous, ...link, ...representative, ...balance, ...signature])
const transport = await this.DynamicTransport.create(this.openTimeout, this.listenTimeout)
- const response = await transport.send(0xa1, 0x03, 0x00, 0x00, data as Buffer)
+ const response = await transport.send(Ledger.#adpu.class, Ledger.#adpu.cacheBlock, Ledger.#adpu.paramUnused, Ledger.#adpu.paramUnused, data as Buffer)
.then(res => bytes.toDec(res))
.catch(err => err.statusCode) as number
await transport.close()
* @param {object} block - Block data to sign
* @returns {Promise} Status, signature, and block hash
*/
- async sign (index: number, block: SendBlock | ReceiveBlock | ChangeBlock): Promise<{ status: string, signature: string, hash: string }>
+ async sign (index: number, block: SendBlock | ReceiveBlock | ChangeBlock): Promise<LedgerSignResponse>
/**
* Sign a nonce with the Ledger device.
*
* @param {string} nonce - 128-bit string to sign
* @returns {Promise} Status and signature
*/
- async sign (index: number, nonce: string): Promise<{ status: string, signature: string }>
- async sign (index: number = 0, input: string | SendBlock | ReceiveBlock | ChangeBlock): Promise<{ status: string, signature: string | null, hash?: string | null }> {
+ async sign (index: number, nonce: string): Promise<LedgerSignResponse>
+ async sign (index: number = 0, input: string | SendBlock | ReceiveBlock | ChangeBlock): Promise<LedgerSignResponse> {
if (typeof index !== 'number' || index < 0 || index >= HARDENED_OFFSET) {
throw new TypeError('Invalid account index')
}
if (nonce.length !== 16) {
throw new RangeError('Nonce must be 16-byte string')
}
- const data = new Uint8Array([0x03, ...purpose, ...coin, ...account, ...nonce])
- const response = await transport.send(0xa1, 0x05, 0x00, 0x00, data as Buffer)
+ const data = new Uint8Array([Ledger.#adpu.bip32DerivationLevel, ...purpose, ...coin, ...account, ...nonce])
+ const response = await transport.send(Ledger.#adpu.class, Ledger.#adpu.signNonce, Ledger.#adpu.paramUnused, Ledger.#adpu.paramUnused, data as Buffer)
.catch(err => dec.toBytes(err.statusCode)) as Uint8Array
await transport.close()
const link = hex.toBytes(input.link)
const representative = hex.toBytes(input.representative.publicKey)
const balance = hex.toBytes(BigInt(input.balance).toString(16), 16)
- const data = new Uint8Array([0x03, ...purpose, ...coin, ...account, ...previous, ...link, ...representative, ...balance])
- const response = await transport.send(0xa1, 0x04, 0x00, 0x00, data as Buffer)
+ const data = new Uint8Array([Ledger.#adpu.bip32DerivationLevel, ...purpose, ...coin, ...account, ...previous, ...link, ...representative, ...balance])
+ const response = await transport.send(Ledger.#adpu.class, Ledger.#adpu.signBlock, Ledger.#adpu.paramUnused, Ledger.#adpu.paramUnused, data as Buffer)
.catch(err => dec.toBytes(err.statusCode)) as Uint8Array
await transport.close()
if (response.length === 2) {
const statusCode = bytes.toDec(response) as number
const status = LEDGER_STATUS_CODES[statusCode] ?? 'UNKNOWN_ERROR'
- return { status, signature: null, hash: null }
+ return { status, signature: null }
}
const hash = bytes.toHex(response.slice(0, 32))
* @param {number} index - Account number
* @param {object} block - JSON-formatted block data
*/
- async updateCache (index: number, block: { [key: string]: string }): Promise<{ status: string }>
+ async updateCache (index: number, block: { [key: string]: string }): Promise<LedgerResponse>
/**
* Update cache from a block hash by calling out to a node. Suitable for online
* use only.
* @param {string} hash - Hexadecimal block hash
* @param {Rpc} rpc - Rpc class object with a node URL
*/
- async updateCache (index: number, hash: string, rpc: Rpc): Promise<{ status: string }>
- async updateCache (index: number, input: any, node?: Rpc): Promise<{ status: string }> {
+ async updateCache (index: number, hash: string, rpc: Rpc): Promise<LedgerResponse>
+ async updateCache (index: number, input: any, node?: Rpc): Promise<LedgerResponse> {
if (typeof input === 'string' && node?.constructor === Rpc) {
const data = {
'json_block': 'true',
if (this.#queue.length > 0) {
this.#queue.push(job)
} else {
- for (const thread of this.#threads) this.#assign(thread, job)
+ for (const thread of this.#threads) {
+ this.#assign(thread, job)
+ }
}
})
}
+ terminate (): void {
+ for (const thread of this.#threads) {
+ thread.job = null
+ thread.worker.terminate()
+ }
+ }
+
/**
+ * Creates a Web Worker from a stringified script.
*
- * @param {string} worker - Stringified worker class
+ * @param {string} worker - Stringified worker class body
* @param {number} [count=1] - Integer between 1 and CPU thread count shared among all Pools
*/
constructor (worker: string, count: number = 1) {
job: null
}
thread.worker.addEventListener('message', message => {
- let result = JSON.parse(new TextDecoder().decode(message.data) || "[]")
+ let result = JSON.parse(new TextDecoder().decode(message.data) || '[]')
if (!Array.isArray(result)) result = [result]
this.#report(thread, result)
})
// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
// SPDX-License-Identifier: GPL-3.0-or-later
-import { Account } from './account.js'
+import { Account } from './account'
type RolodexEntry = {
name: string
// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
// SPDX-License-Identifier: GPL-3.0-or-later
-import { buffer, hex, utf8 } from './convert.js'
-import { Entropy } from './entropy.js'
+import { buffer, hex, utf8 } from './convert'
+import { Entropy } from './entropy'
+
const { subtle } = globalThis.crypto
const ERR_MSG = 'Failed to store item in Safe'
this.#storage = globalThis.sessionStorage
}
+ /**
+ * Removes data from the Safe without decrypting.
+ */
+ destroy (name: string): void {
+ try {
+ this.#storage.removeItem(name)
+ } catch (err) {
+ console.log(err)
+ }
+ }
+
/**
* Encrypts data with a password and stores it in the Safe.
*/
*/
async put (name: string, key: CryptoKey, data: any): Promise<boolean>
async put (name: string, passkey: string | CryptoKey, data: any): Promise<boolean> {
+ if (typeof passkey === 'string') {
+ try {
+ passkey = await subtle.importKey('raw', utf8.toBytes(passkey), 'PBKDF2', false, ['deriveBits', 'deriveKey'])
+ } catch {
+ throw new Error(ERR_MSG)
+ }
+ }
if (this.#storage.getItem(name)) {
throw new Error(ERR_MSG)
}
- return this.overwrite(name, passkey as string, data)
+ return this.overwrite(name, passkey, data)
}
/**
*/
async overwrite (name: string, key: CryptoKey, data: any): Promise<boolean>
async overwrite (name: string, passkey: string | CryptoKey, data: any): Promise<boolean> {
- if (this.#isNotValid(name, passkey, data)) {
+ if (typeof passkey === 'string') {
+ try {
+ passkey = await subtle.importKey('raw', utf8.toBytes(passkey), 'PBKDF2', false, ['deriveBits', 'deriveKey'])
+ } catch {
+ throw new Error(ERR_MSG)
+ }
+ }
+ if (this.#isInvalid(name, passkey, data)) {
throw new Error(ERR_MSG)
}
const iv = await Entropy.create()
- if (typeof passkey === 'string') {
+ if (passkey.usages.includes('deriveKey')) {
try {
- passkey = await subtle.importKey('raw', utf8.toBytes(passkey), 'PBKDF2', false, ['deriveBits', 'deriveKey'])
- passkey = await subtle.deriveKey({ name: 'PBKDF2', hash: 'SHA-512', salt: iv.bytes, iterations: 210000 }, passkey, { name: 'AES-GCM', length: 256 }, false, ['encrypt'])
- } catch (err) {
+ const derivationAlgorithm: Pbkdf2Params = {
+ name: 'PBKDF2',
+ hash: 'SHA-512',
+ salt: iv.bytes,
+ iterations: 210000
+ }
+ const derivedKeyType: AesKeyGenParams = {
+ name: 'AES-GCM',
+ length: 256
+ }
+ passkey = await subtle.deriveKey(derivationAlgorithm, passkey, derivedKeyType, false, ['encrypt'])
+ } catch {
throw new Error(ERR_MSG)
}
}
data = data.toString()
}
data = JSON.stringify(data)
- const encoded = utf8.toBytes(data)
- const encrypted = await subtle.encrypt({ name: 'AES-GCM', iv: iv.buffer }, passkey, encoded)
+ const encrypted = await subtle.encrypt({ name: 'AES-GCM', iv: iv.buffer }, passkey, utf8.toBytes(data))
const record = {
encrypted: buffer.toHex(encrypted),
iv: iv.hex
}
- await new Promise<void>((resolve, reject) => {
- try {
- this.#storage.setItem(name, JSON.stringify(record))
- resolve()
- } catch (err) {
- reject(err)
- }
- })
- passkey = ''
+ this.#storage.setItem(name, JSON.stringify(record))
} catch (err) {
throw new Error(ERR_MSG)
}
*/
async get (name: string, key: CryptoKey): Promise<any>
async get (name: string, passkey: string | CryptoKey): Promise<any> {
- if (this.#isNotValid(name, passkey)) {
+ if (typeof passkey === 'string') {
+ try {
+ passkey = await subtle.importKey('raw', utf8.toBytes(passkey), 'PBKDF2', false, ['deriveBits', 'deriveKey'])
+ } catch {
+ return null
+ }
+ }
+ if (this.#isInvalid(name, passkey)) {
return null
}
- const item = await new Promise<string | null>(resolve => {
- resolve(this.#storage.getItem(name))
- })
+ const item = this.#storage.getItem(name)
if (item == null) {
return null
}
const iv = await Entropy.import(record.iv)
try {
- if (typeof passkey === 'string') {
- passkey = await subtle.importKey('raw', utf8.toBytes(passkey), 'PBKDF2', false, ['deriveBits', 'deriveKey'])
- passkey = await subtle.deriveKey({ name: 'PBKDF2', hash: 'SHA-512', salt: iv.bytes, iterations: 210000 }, passkey, { name: 'AES-GCM', length: 256 }, false, ['decrypt'])
+ if (passkey.usages.includes('deriveKey')) {
+ const derivationAlgorithm: Pbkdf2Params = {
+ name: 'PBKDF2',
+ hash: 'SHA-512',
+ salt: iv.bytes,
+ iterations: 210000
+ }
+ const derivedKeyType: AesKeyGenParams = {
+ name: 'AES-GCM',
+ length: 256
+ }
+ passkey = await subtle.deriveKey(derivationAlgorithm, passkey, derivedKeyType, false, ['decrypt'])
}
} catch (err) {
return null
const decrypted = await subtle.decrypt({ name: 'AES-GCM', iv: iv.buffer }, passkey, encrypted)
const decoded = buffer.toUtf8(decrypted)
const data = JSON.parse(decoded)
- passkey = ''
this.#storage.removeItem(name)
return data
} catch (err) {
}
}
- #isNotValid (name: string, passkey: string | CryptoKey, data?: any): boolean {
+ #isInvalid (name: string, passkey: string | CryptoKey, data?: any): boolean {
if (typeof name !== 'string' || name === '') {
return true
}
// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
// SPDX-License-Identifier: GPL-3.0-or-later
-import { Account } from './account.js'
-import { Blake2b } from './blake2b.js'
-import { UNITS } from './constants.js'
-import { hex } from './convert.js'
-import { Rpc } from './rpc.js'
-import { Bip44Wallet, Blake2bWallet, LedgerWallet } from './wallet.js'
-import { SendBlock } from './block.js'
-import { NanoNaCl } from './workers/nano-nacl.js'
+import { Account } from './account'
+import { Blake2b } from './blake2b'
+import { SendBlock } from './block'
+import { UNITS } from './constants'
+import { hex } from './convert'
+import { Rpc } from './rpc'
+import { Bip44Wallet, Blake2bWallet, LedgerWallet } from './wallet'
+import { NanoNaCl } from '#workers'
+
+type SweepResult = {
+ status: "success" | "error"
+ address: string
+ message: string
+}
function hash (data: string | string[], encoding?: 'hex'): string {
if (!Array.isArray(data)) data = [data]
* @param {number} to - Ending account index to sweep
* @returns An array of results including both successes and failures
*/
-export async function sweep (rpc: Rpc | string | URL, wallet: Blake2bWallet | Bip44Wallet | LedgerWallet, recipient: string, from: number = 0, to: number = from) {
+export async function sweep (
+ rpc: Rpc | string | URL,
+ wallet: Blake2bWallet | Bip44Wallet | LedgerWallet,
+ recipient: string,
+ from: number = 0,
+ to: number = from
+): Promise<SweepResult[]> {
if (rpc == null || wallet == null || recipient == null) {
throw new ReferenceError('Missing required sweep arguments')
}
// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>\r
// SPDX-License-Identifier: GPL-3.0-or-later\r
\r
-import { Account } from './account.js'\r
-import { Blake2b } from './blake2b.js'\r
-import { Bip39Mnemonic } from './bip39-mnemonic.js'\r
-import { ADDRESS_GAP, SEED_LENGTH_BIP44, SEED_LENGTH_BLAKE2B } from './constants.js'\r
-import { Entropy } from './entropy.js'\r
-import { Pool } from './pool.js'\r
-import { Rpc } from './rpc.js'\r
-import { Safe } from './safe.js'\r
-import { Bip44Ckd, NanoNaCl } from './workers.js'\r
-import type { Ledger } from './ledger.js'\r
+import { Account, AccountList } from './account'\r
+import { Bip39Mnemonic } from './bip39-mnemonic'\r
+import { Blake2b } from './blake2b'\r
+import { ADDRESS_GAP, SEED_LENGTH_BIP44, SEED_LENGTH_BLAKE2B } from './constants'\r
+import { hex } from './convert'\r
+import { Entropy } from './entropy'\r
+import { Ledger } from './ledger'\r
+import { Pool } from './pool'\r
+import { Rpc } from './rpc'\r
+import { Safe } from './safe'\r
+import { Bip44CkdWorker, NanoNaClWorker } from '#workers'\r
\r
type KeyPair = {\r
publicKey?: string,\r
privateKey?: string,\r
index?: number\r
}\r
+\r
/**\r
* Represents a wallet containing numerous Nano accounts derived from a single\r
* source, the form of which can vary based on the type of wallet. The Wallet\r
* Blake2bWallet, LedgerWallet.\r
*/\r
abstract class Wallet {\r
- #accounts: Account[]\r
+ #accounts: AccountList\r
#id: Entropy\r
#locked: boolean = true\r
#mnemonic: Bip39Mnemonic | null\r
if (this.constructor === Wallet) {\r
throw new Error('Wallet is an abstract class and cannot be instantiated directly.')\r
}\r
- this.#accounts = []\r
+ this.#accounts = new AccountList()\r
this.#id = id\r
this.#mnemonic = mnemonic ?? null\r
- this.#poolNanoNacl = new Pool(NanoNaCl)\r
+ this.#poolNanoNacl = new Pool(NanoNaClWorker)\r
this.#safe = new Safe()\r
this.#seed = seed ?? null\r
}\r
\r
/**\r
- * Retrieves accounts from a wallet using its child key derivation function.\r
+ * Removes encrypted secrets in storage and releases variable references to\r
+ * allow garbage collection.\r
+ */\r
+ destroy (): void {\r
+ let i = 0\r
+ for (const a in this.#accounts) {\r
+ this.#accounts[a].destroy()\r
+ delete this.#accounts[a]\r
+ i++\r
+ }\r
+ this.#safe.destroy(this.id)\r
+ this.#mnemonic = null\r
+ this.#seed = null\r
+ this.#poolNanoNacl.terminate()\r
+ }\r
+\r
+ /**\r
+ * Retrieves an account from a wallet using its child key derivation function.\r
* Defaults to the first account at index 0.\r
*\r
- * Note: The wallet index of a given requested account might not correlate with\r
- * its index in the returned array.\r
- *\r
- * For example, calling `await wallet.accounts(5)` will return the sixth\r
- * account of the wallet in the first array element position at index 0.\r
+ * ```\r
+ * console.log(await wallet.account(5))\r
+ * // outputs sixth account of the wallet\r
+ * // {\r
+ * // privateKey: <...>,\r
+ * // index: 5\r
+ * // }\r
+ * ```\r
+ *\r
+ * @param {number} index - Wallet index of secret key. Default: 0\r
+ * @returns {Account} Account derived at the specified wallet index\r
+ */\r
+ async account (index: number = 0): Promise<Account> {\r
+ return (await this.accounts(index))[index]\r
+ }\r
+\r
+ /**\r
+ * Retrieves accounts from a wallet using its child key derivation function.\r
+ * Defaults to the first account at index 0.\r
*\r
- * A shorthand way of getting one specific account could be\r
- * `const account = (await wallet.accounts(N))[0]` where N is the wallet index\r
- * of the desired account.\r
+ * The returned object will have keys corresponding with the requested range\r
+ * of account indexes. The value of each key will be the Account derived for\r
+ * that index in the wallet.\r
+ *\r
+ * ```\r
+ * console.log(await wallet.accounts(5))\r
+ * // outputs sixth account of the wallet\r
+ * // {\r
+ * // 5: {\r
+ * // privateKey: <...>,\r
+ * // index: 5\r
+ * // }\r
+ * // }\r
+ * ```\r
*\r
* @param {number} from - Start index of secret keys. Default: 0\r
* @param {number} to - End index of secret keys. Default: `from`\r
+ * @returns {AccountList} Object with keys of account indexes and values of the corresponding Accounts\r
*/\r
- async accounts (from: number = 0, to: number = from): Promise<Account[]> {\r
+ async accounts (from: number = 0, to: number = from): Promise<AccountList> {\r
if (from > to) {\r
const swap = from\r
from = to\r
to = swap\r
}\r
+ const output = new AccountList()\r
const indexes: number[] = []\r
for (let i = from; i <= to; i++) {\r
if (this.#accounts[i] == null) {\r
indexes.push(i)\r
+ } else {\r
+ output[i] = this.#accounts[i]\r
}\r
}\r
if (indexes.length > 0) {\r
let results = await this.ckd(indexes)\r
const data: any = []\r
- results.forEach(r => data.push({ privateKey: r.privateKey, index: r.index }))\r
+ results.forEach(r => data.push({\r
+ method: 'convert',\r
+ privateKey: r.privateKey,\r
+ index: r.index\r
+ }))\r
const keypairs: KeyPair[] = await this.#poolNanoNacl.assign(data)\r
for (const keypair of keypairs) {\r
if (keypair.privateKey == null) throw new RangeError('Account private key missing')\r
if (keypair.publicKey == null) throw new RangeError('Account public key missing')\r
if (keypair.index == null) throw new RangeError('Account keys derived but index missing')\r
- const { privateKey, publicKey, index } = keypair\r
- this.#accounts[keypair.index] = Account.fromKeypair(privateKey, publicKey, index)\r
+ const { privateKey, index } = keypair\r
+ output[keypair.index] = Account.fromPrivateKey(privateKey, index)\r
+ this.#accounts[keypair.index] = output[keypair.index]\r
}\r
}\r
- return this.#accounts.slice(from, to + 1)\r
+ return output\r
}\r
\r
/**\r
* @param {number} from - Account index from which to start the search\r
* @returns {Promise<Account>} The lowest-indexed unopened account belonging to the wallet\r
*/\r
-\r
async getNextNewAccount (rpc: Rpc, batchSize: number = ADDRESS_GAP, from: number = 0): Promise<Account> {\r
if (!Number.isSafeInteger(batchSize) || batchSize < 1) {\r
throw new RangeError(`Invalid batch size ${batchSize}`)\r
}\r
const accounts = await this.accounts(from, from + batchSize - 1)\r
- const addresses = accounts.map(({ address }) => address)\r
+ const addresses = []\r
+ for (const a in accounts) {\r
+ addresses.push(accounts[a].address)\r
+ }\r
const data = {\r
"accounts": addresses\r
}\r
* @param {Rpc|string|URL} rpc - RPC node information required to refresh accounts, calculate PoW, and process blocks\r
* @returns {Promise<Account[]>} Accounts with updated balances, frontiers, and representatives\r
*/\r
- async refresh (rpc: Rpc | string | URL, from: number = 0, to: number = from): Promise<Account[]> {\r
+ async refresh (rpc: Rpc | string | URL, from: number = 0, to: number = from): Promise<AccountList> {\r
if (typeof rpc === 'string' || rpc.constructor === URL) {\r
rpc = new Rpc(rpc)\r
}\r
throw new TypeError('RPC must be a valid node')\r
}\r
const accounts = await this.accounts(from, to)\r
- for (let i = 0; i < accounts.length; i++) {\r
+ for (const a in accounts) {\r
try {\r
- await accounts[i].refresh(rpc)\r
+ await accounts[a].refresh(rpc)\r
} catch (err) {\r
- accounts.splice(i--, 1)\r
+ delete accounts[a]\r
}\r
}\r
return accounts\r
data.seed = this.#seed\r
}\r
success &&= await this.#safe.put(this.id, passkey as string, data)\r
- await Promise.all(this.#accounts.map((a) => a.lock(passkey as string)))\r
+ const promises = []\r
+ for (const account of this.#accounts) {\r
+ promises.push(account.lock(passkey as string))\r
+ }\r
+ await Promise.all(promises)\r
if (!success) {\r
throw null\r
}\r
if (id !== this.id) {\r
throw null\r
}\r
- await Promise.all(this.#accounts.map((a) => a.unlock(passkey as string)))\r
+ const promises = []\r
+ for (const account of this.#accounts) {\r
+ promises.push(account.unlock(passkey as string))\r
+ }\r
+ await Promise.all(promises)\r
if (mnemonic != null) {\r
this.#mnemonic = await Bip39Mnemonic.fromPhrase(mnemonic)\r
}\r
*/\r
export class Bip44Wallet extends Wallet {\r
static #isInternal: boolean = false\r
- static #poolBip44Ckd: Pool = new Pool(Bip44Ckd)\r
+ #poolBip44Ckd: Pool\r
\r
constructor (id: Entropy, seed: string, mnemonic?: Bip39Mnemonic) {\r
if (!Bip44Wallet.#isInternal) {\r
}\r
Bip44Wallet.#isInternal = false\r
super(id, seed, mnemonic)\r
+ this.#poolBip44Ckd = new Pool(Bip44CkdWorker)\r
+ }\r
+\r
+ /**\r
+ * Removes encrypted secrets in storage and releases variable references to\r
+ * allow garbage collection.\r
+ */\r
+ destroy () {\r
+ super.destroy()\r
+ this.#poolBip44Ckd.terminate()\r
}\r
\r
/**\r
async ckd (indexes: number[]): Promise<KeyPair[]> {\r
const data: any = []\r
indexes.forEach(i => data.push({ seed: this.seed, index: i }))\r
- const privateKeys: KeyPair[] = await Bip44Wallet.#poolBip44Ckd.assign(data)\r
+ const privateKeys: KeyPair[] = await this.#poolBip44Ckd.assign(data)\r
return privateKeys\r
}\r
}\r
const results = indexes.map(index => {\r
const indexHex = index.toString(16).padStart(8, '0').toUpperCase()\r
const inputHex = `${this.seed}${indexHex}`.padStart(72, '0')\r
- const inputArray = (inputHex.match(/.{1,2}/g) ?? []).map(h => parseInt(h, 16))\r
- const inputBytes = Uint8Array.from(inputArray)\r
+ const inputBytes = hex.toBytes(inputHex)\r
const privateKey: string = new Blake2b(32).update(inputBytes).digest('hex')\r
return { privateKey, index }\r
})\r
* @returns {LedgerWallet} A wallet containing accounts and a Ledger device communication object\r
*/\r
static async create (): Promise<LedgerWallet> {\r
- const { Ledger } = await import('./ledger.js')\r
+ const { Ledger } = await import('./ledger')\r
const l = await Ledger.init()\r
const id = await Entropy.create(16)\r
LedgerWallet.#isInternal = true\r
if (typeof id !== 'string' || id === '') {\r
throw new TypeError('Wallet ID is required to restore')\r
}\r
- const { Ledger } = await import('./ledger.js')\r
+ const { Ledger } = await import('./ledger')\r
const l = await Ledger.init()\r
LedgerWallet.#isInternal = true\r
return new this(await Entropy.import(id), l)\r
return false\r
}\r
const result = await this.ledger.close()\r
- return result === 'OK'\r
+ return result.status === 'OK'\r
}\r
\r
/**\r
+++ /dev/null
-// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
-// SPDX-License-Identifier: GPL-3.0-or-later
-import { default as Bip44Ckd } from './workers/bip44-ckd.js'
-import { default as NanoNaCl } from './workers/nano-nacl.js'
-import { default as Pow } from './workers/powgl.js'
-
-export { Bip44Ckd, NanoNaCl, Pow }
// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
// SPDX-License-Identifier: GPL-3.0-or-later
-import { WorkerInterface } from '../pool.js'
+import { WorkerInterface } from '#src/lib/pool.js'
type ExtendedKey = {
privateKey: DataView
--- /dev/null
+// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
+// SPDX-License-Identifier: GPL-3.0-or-later
+import { default as Bip44CkdWorker, Bip44Ckd } from './bip44-ckd'
+import { default as NanoNaClWorker, NanoNaCl } from './nano-nacl'
+
+export {
+ Bip44Ckd,
+ Bip44CkdWorker,
+ NanoNaCl,
+ NanoNaClWorker
+}
\r
'use strict'\r
\r
-import { Blake2b } from '../blake2b.js'\r
-import { WorkerInterface } from '../pool.js'\r
+import { Blake2b } from '#src/lib/blake2b.js'\r
+import { WorkerInterface } from '#src/lib/pool.js'\r
\r
// Ported in 2014 by Dmitry Chestnykh and Devi Mandiri.\r
// Public domain.\r
return new Promise(async (resolve, reject): Promise<void> => {\r
for (let d of data) {\r
try {\r
- d.publicKey = await this.convert(d.privateKey)\r
+ switch (d.method) {\r
+ case 'detached': {\r
+ d.signature = await this.detached(Uint8Array.from(d.msg), Uint8Array.from(d.secretKey))\r
+ break\r
+ }\r
+ case 'convert': {\r
+ d.publicKey = await this.convert(d.privateKey)\r
+ break\r
+ }\r
+ default: {\r
+ throw new TypeError(`unknown NanoNaCl method ${d.method}`)\r
+ }\r
+ }\r
} catch (err) {\r
reject(err)\r
}\r
\r
static gf = function (init?: number[]): Float64Array {\r
const r = new Float64Array(16)\r
- if (init) for (let i = 0; i < init.length; i++) r[i] = init[i]\r
+ if (init) for (let i = 0; i < init.length; i++) {\r
+ r[i] = init[i]\r
+ }\r
return r\r
}\r
\r
\r
static vn (x: Uint8Array, xi: number, y: Uint8Array, yi: number, n: number): number {\r
let d = 0\r
- for (let i = 0; i < n; i++) d |= x[xi + i] ^ y[yi + i]\r
+ for (let i = 0; i < n; i++) {\r
+ d |= x[xi + i] ^ y[yi + i]\r
+ }\r
return (1 & ((d - 1) >>> 8)) - 1\r
}\r
\r
}\r
\r
static set25519 (r: Float64Array, a: Float64Array): void {\r
- for (let i = 0; i < 16; i++) r[i] = a[i] | 0\r
+ for (let i = 0; i < 16; i++) {\r
+ r[i] = a[i] | 0\r
+ }\r
}\r
\r
static car25519 (o: Float64Array): void {\r
c = Math.floor(v / 65536)\r
o[i] = v - c * 65536\r
}\r
- o[0] += c - 1 + 37 * (c - 1)\r
+ o[0] += 38 * (c - 1)\r
}\r
\r
static sel25519 (p: Float64Array, q: Float64Array, b: number): void {\r
let b: number\r
const m: Float64Array = this.gf()\r
const t: Float64Array = this.gf()\r
- for (let i = 0; i < 16; i++) t[i] = n[i]\r
+ for (let i = 0; i < 16; i++) {\r
+ t[i] = n[i]\r
+ }\r
this.car25519(t)\r
this.car25519(t)\r
this.car25519(t)\r
}\r
\r
static par25519 (a: Float64Array): number {\r
- var d = new Uint8Array(32)\r
+ const d = new Uint8Array(32)\r
this.pack25519(d, a)\r
return d[0] & 1\r
}\r
\r
static unpack25519 (o: Float64Array, n: Uint8Array): void {\r
- for (let i = 0; i < 16; i++) o[i] = n[2 * i] + (n[2 * i + 1] << 8)\r
- o[15] &= 0x7fff\r
+ for (let i = 0; i < 16; i++) {\r
+ o[i] = n[2 * i] + (n[2 * i + 1] << 8)\r
+ }\r
+ o[15] &= (1 << 15) - 1\r
}\r
\r
static A (o: Float64Array, a: Float64Array, b: Float64Array): void {\r
- for (let i = 0; i < 16; i++) o[i] = a[i] + b[i]\r
+ for (let i = 0; i < 16; i++) {\r
+ o[i] = a[i] + b[i]\r
+ }\r
}\r
\r
static Z (o: Float64Array, a: Float64Array, b: Float64Array): void {\r
- for (let i = 0; i < 16; i++) o[i] = a[i] - b[i]\r
+ for (let i = 0; i < 16; i++) {\r
+ o[i] = a[i] - b[i]\r
+ }\r
}\r
\r
static M (o: Float64Array, a: Float64Array, b: Float64Array): void {\r
- let v, c,\r
- t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0,\r
- t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0,\r
- t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0,\r
- t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0,\r
- b0 = b[0],\r
- b1 = b[1],\r
- b2 = b[2],\r
- b3 = b[3],\r
- b4 = b[4],\r
- b5 = b[5],\r
- b6 = b[6],\r
- b7 = b[7],\r
- b8 = b[8],\r
- b9 = b[9],\r
- b10 = b[10],\r
- b11 = b[11],\r
- b12 = b[12],\r
- b13 = b[13],\r
- b14 = b[14],\r
- b15 = b[15]\r
-\r
- v = a[0]\r
- t0 += v * b0\r
- t1 += v * b1\r
- t2 += v * b2\r
- t3 += v * b3\r
- t4 += v * b4\r
- t5 += v * b5\r
- t6 += v * b6\r
- t7 += v * b7\r
- t8 += v * b8\r
- t9 += v * b9\r
- t10 += v * b10\r
- t11 += v * b11\r
- t12 += v * b12\r
- t13 += v * b13\r
- t14 += v * b14\r
- t15 += v * b15\r
- v = a[1]\r
- t1 += v * b0\r
- t2 += v * b1\r
- t3 += v * b2\r
- t4 += v * b3\r
- t5 += v * b4\r
- t6 += v * b5\r
- t7 += v * b6\r
- t8 += v * b7\r
- t9 += v * b8\r
- t10 += v * b9\r
- t11 += v * b10\r
- t12 += v * b11\r
- t13 += v * b12\r
- t14 += v * b13\r
- t15 += v * b14\r
- t16 += v * b15\r
- v = a[2]\r
- t2 += v * b0\r
- t3 += v * b1\r
- t4 += v * b2\r
- t5 += v * b3\r
- t6 += v * b4\r
- t7 += v * b5\r
- t8 += v * b6\r
- t9 += v * b7\r
- t10 += v * b8\r
- t11 += v * b9\r
- t12 += v * b10\r
- t13 += v * b11\r
- t14 += v * b12\r
- t15 += v * b13\r
- t16 += v * b14\r
- t17 += v * b15\r
- v = a[3]\r
- t3 += v * b0\r
- t4 += v * b1\r
- t5 += v * b2\r
- t6 += v * b3\r
- t7 += v * b4\r
- t8 += v * b5\r
- t9 += v * b6\r
- t10 += v * b7\r
- t11 += v * b8\r
- t12 += v * b9\r
- t13 += v * b10\r
- t14 += v * b11\r
- t15 += v * b12\r
- t16 += v * b13\r
- t17 += v * b14\r
- t18 += v * b15\r
- v = a[4]\r
- t4 += v * b0\r
- t5 += v * b1\r
- t6 += v * b2\r
- t7 += v * b3\r
- t8 += v * b4\r
- t9 += v * b5\r
- t10 += v * b6\r
- t11 += v * b7\r
- t12 += v * b8\r
- t13 += v * b9\r
- t14 += v * b10\r
- t15 += v * b11\r
- t16 += v * b12\r
- t17 += v * b13\r
- t18 += v * b14\r
- t19 += v * b15\r
- v = a[5]\r
- t5 += v * b0\r
- t6 += v * b1\r
- t7 += v * b2\r
- t8 += v * b3\r
- t9 += v * b4\r
- t10 += v * b5\r
- t11 += v * b6\r
- t12 += v * b7\r
- t13 += v * b8\r
- t14 += v * b9\r
- t15 += v * b10\r
- t16 += v * b11\r
- t17 += v * b12\r
- t18 += v * b13\r
- t19 += v * b14\r
- t20 += v * b15\r
- v = a[6]\r
- t6 += v * b0\r
- t7 += v * b1\r
- t8 += v * b2\r
- t9 += v * b3\r
- t10 += v * b4\r
- t11 += v * b5\r
- t12 += v * b6\r
- t13 += v * b7\r
- t14 += v * b8\r
- t15 += v * b9\r
- t16 += v * b10\r
- t17 += v * b11\r
- t18 += v * b12\r
- t19 += v * b13\r
- t20 += v * b14\r
- t21 += v * b15\r
- v = a[7]\r
- t7 += v * b0\r
- t8 += v * b1\r
- t9 += v * b2\r
- t10 += v * b3\r
- t11 += v * b4\r
- t12 += v * b5\r
- t13 += v * b6\r
- t14 += v * b7\r
- t15 += v * b8\r
- t16 += v * b9\r
- t17 += v * b10\r
- t18 += v * b11\r
- t19 += v * b12\r
- t20 += v * b13\r
- t21 += v * b14\r
- t22 += v * b15\r
- v = a[8]\r
- t8 += v * b0\r
- t9 += v * b1\r
- t10 += v * b2\r
- t11 += v * b3\r
- t12 += v * b4\r
- t13 += v * b5\r
- t14 += v * b6\r
- t15 += v * b7\r
- t16 += v * b8\r
- t17 += v * b9\r
- t18 += v * b10\r
- t19 += v * b11\r
- t20 += v * b12\r
- t21 += v * b13\r
- t22 += v * b14\r
- t23 += v * b15\r
- v = a[9]\r
- t9 += v * b0\r
- t10 += v * b1\r
- t11 += v * b2\r
- t12 += v * b3\r
- t13 += v * b4\r
- t14 += v * b5\r
- t15 += v * b6\r
- t16 += v * b7\r
- t17 += v * b8\r
- t18 += v * b9\r
- t19 += v * b10\r
- t20 += v * b11\r
- t21 += v * b12\r
- t22 += v * b13\r
- t23 += v * b14\r
- t24 += v * b15\r
- v = a[10]\r
- t10 += v * b0\r
- t11 += v * b1\r
- t12 += v * b2\r
- t13 += v * b3\r
- t14 += v * b4\r
- t15 += v * b5\r
- t16 += v * b6\r
- t17 += v * b7\r
- t18 += v * b8\r
- t19 += v * b9\r
- t20 += v * b10\r
- t21 += v * b11\r
- t22 += v * b12\r
- t23 += v * b13\r
- t24 += v * b14\r
- t25 += v * b15\r
- v = a[11]\r
- t11 += v * b0\r
- t12 += v * b1\r
- t13 += v * b2\r
- t14 += v * b3\r
- t15 += v * b4\r
- t16 += v * b5\r
- t17 += v * b6\r
- t18 += v * b7\r
- t19 += v * b8\r
- t20 += v * b9\r
- t21 += v * b10\r
- t22 += v * b11\r
- t23 += v * b12\r
- t24 += v * b13\r
- t25 += v * b14\r
- t26 += v * b15\r
- v = a[12]\r
- t12 += v * b0\r
- t13 += v * b1\r
- t14 += v * b2\r
- t15 += v * b3\r
- t16 += v * b4\r
- t17 += v * b5\r
- t18 += v * b6\r
- t19 += v * b7\r
- t20 += v * b8\r
- t21 += v * b9\r
- t22 += v * b10\r
- t23 += v * b11\r
- t24 += v * b12\r
- t25 += v * b13\r
- t26 += v * b14\r
- t27 += v * b15\r
- v = a[13]\r
- t13 += v * b0\r
- t14 += v * b1\r
- t15 += v * b2\r
- t16 += v * b3\r
- t17 += v * b4\r
- t18 += v * b5\r
- t19 += v * b6\r
- t20 += v * b7\r
- t21 += v * b8\r
- t22 += v * b9\r
- t23 += v * b10\r
- t24 += v * b11\r
- t25 += v * b12\r
- t26 += v * b13\r
- t27 += v * b14\r
- t28 += v * b15\r
- v = a[14]\r
- t14 += v * b0\r
- t15 += v * b1\r
- t16 += v * b2\r
- t17 += v * b3\r
- t18 += v * b4\r
- t19 += v * b5\r
- t20 += v * b6\r
- t21 += v * b7\r
- t22 += v * b8\r
- t23 += v * b9\r
- t24 += v * b10\r
- t25 += v * b11\r
- t26 += v * b12\r
- t27 += v * b13\r
- t28 += v * b14\r
- t29 += v * b15\r
- v = a[15]\r
- t15 += v * b0\r
- t16 += v * b1\r
- t17 += v * b2\r
- t18 += v * b3\r
- t19 += v * b4\r
- t20 += v * b5\r
- t21 += v * b6\r
- t22 += v * b7\r
- t23 += v * b8\r
- t24 += v * b9\r
- t25 += v * b10\r
- t26 += v * b11\r
- t27 += v * b12\r
- t28 += v * b13\r
- t29 += v * b14\r
- t30 += v * b15\r
-\r
- t0 += 38 * t16\r
- t1 += 38 * t17\r
- t2 += 38 * t18\r
- t3 += 38 * t19\r
- t4 += 38 * t20\r
- t5 += 38 * t21\r
- t6 += 38 * t22\r
- t7 += 38 * t23\r
- t8 += 38 * t24\r
- t9 += 38 * t25\r
- t10 += 38 * t26\r
- t11 += 38 * t27\r
- t12 += 38 * t28\r
- t13 += 38 * t29\r
- t14 += 38 * t30\r
+ let v, c, s = 1 << 16, t = new Array(31)\r
+ t.fill(0)\r
+\r
+ // init t values\r
+ for (let i = 0; i < 16; i++) {\r
+ for (let j = 0; j < 16; j++) {\r
+ t[i + j] += a[i] * b[j]\r
+ }\r
+ }\r
+\r
+ for (let i = 0; i < 15; i++) {\r
+ t[i] += 38 * t[i + 16]\r
+ }\r
// t15 left as is\r
\r
- // first car\r
+ // first carry\r
c = 1\r
- v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536\r
- v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536\r
- v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536\r
- v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536\r
- v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536\r
- v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536\r
- v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536\r
- v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536\r
- v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536\r
- v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536\r
- v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536\r
- v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536\r
- v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536\r
- v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536\r
- v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536\r
- v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536\r
- t0 += c - 1 + 37 * (c - 1)\r
-\r
- // second car\r
+ for (let i = 0; i < 16; i++) {\r
+ v = t[i] + c + s - 1\r
+ c = Math.floor(v / s)\r
+ t[i] = v - c * s\r
+ }\r
+ t[0] += 38 * (c - 1)\r
+\r
+ // second carry\r
c = 1\r
- v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536\r
- v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536\r
- v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536\r
- v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536\r
- v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536\r
- v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536\r
- v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536\r
- v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536\r
- v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536\r
- v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536\r
- v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536\r
- v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536\r
- v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536\r
- v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536\r
- v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536\r
- v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536\r
- t0 += c - 1 + 37 * (c - 1)\r
-\r
- o[0] = t0\r
- o[1] = t1\r
- o[2] = t2\r
- o[3] = t3\r
- o[4] = t4\r
- o[5] = t5\r
- o[6] = t6\r
- o[7] = t7\r
- o[8] = t8\r
- o[9] = t9\r
- o[10] = t10\r
- o[11] = t11\r
- o[12] = t12\r
- o[13] = t13\r
- o[14] = t14\r
- o[15] = t15\r
+ for (let i = 0; i < 16; i++) {\r
+ v = t[i] + c + s - 1\r
+ c = Math.floor(v / s)\r
+ t[i] = v - c * s\r
+ }\r
+ t[0] += 38 * (c - 1)\r
+\r
+ // assign result to output\r
+ for (let i = 0; i < 16; i++) {\r
+ o[i] = t[i]\r
+ }\r
}\r
\r
static S (o: Float64Array, a: Float64Array): void {\r
}\r
\r
static inv25519 (o: Float64Array, i: Float64Array): void {\r
- const c: Float64Array = this.gf()\r
- for (let a = 0; a < 16; a++) c[a] = i[a]\r
+ const c: Float64Array = new Float64Array(16)\r
+ for (let a = 0; a < 16; a++) {\r
+ c[a] = i[a]\r
+ }\r
for (let a = 253; a >= 0; a--) {\r
this.S(c, c)\r
if (a !== 2 && a !== 4) this.M(c, c, i)\r
}\r
- for (let a = 0; a < 16; a++) o[a] = c[a]\r
+ for (let a = 0; a < 16; a++) {\r
+ o[a] = c[a]\r
+ }\r
}\r
\r
static pow2523 (o: Float64Array, i: Float64Array): void {\r
const c: Float64Array = this.gf()\r
- for (let a = 0; a < 16; a++) c[a] = i[a]\r
+ for (let a = 0; a < 16; a++) {\r
+ c[a] = i[a]\r
+ }\r
for (let a = 250; a >= 0; a--) {\r
this.S(c, c)\r
if (a !== 1) this.M(c, c, i)\r
}\r
- for (let a = 0; a < 16; a++) o[a] = c[a]\r
+ for (let a = 0; a < 16; a++) {\r
+ o[a] = c[a]\r
+ }\r
}\r
\r
// Note: difference from TweetNaCl - BLAKE2b used to hash instead of SHA-512.\r
static crypto_hash (out: Uint8Array, m: Uint8Array, n: number): number {\r
const input = new Uint8Array(n)\r
- for (let i = 0; i < n; ++i) input[i] = m[i]\r
+ for (let i = 0; i < n; ++i) {\r
+ input[i] = m[i]\r
+ }\r
const hash = new Blake2b(64).update(m).digest()\r
- for (let i = 0; i < 64; ++i) out[i] = hash[i]\r
+ for (let i = 0; i < 64; ++i) {\r
+ out[i] = hash[i]\r
+ }\r
return 0\r
}\r
\r
carry = x[j] >> 8\r
x[j] &= 255\r
}\r
- for (j = 0; j < 32; j++) x[j] -= carry * this.L[j]\r
+ for (j = 0; j < 32; j++) {\r
+ x[j] -= carry * this.L[j]\r
+ }\r
for (i = 0; i < 32; i++) {\r
x[i + 1] += x[i] >> 8\r
r[i] = x[i] & 255\r
\r
static reduce (r: Uint8Array): void {\r
let x = new Float64Array(64)\r
- for (let i = 0; i < 64; i++) x[i] = r[i]\r
- for (let i = 0; i < 64; i++) r[i] = 0\r
+ for (let i = 0; i < 64; i++) {\r
+ x[i] = r[i]\r
+ }\r
+ for (let i = 0; i < 64; i++) {\r
+ r[i] = 0\r
+ }\r
this.modL(r, x)\r
}\r
\r
d[31] |= 64\r
\r
const smlen = n + 64\r
- for (let i = 0; i < n; i++) sm[64 + i] = m[i]\r
- for (let i = 0; i < 32; i++) sm[32 + i] = d[32 + i]\r
+ for (let i = 0; i < n; i++) {\r
+ sm[64 + i] = m[i]\r
+ }\r
+ for (let i = 0; i < 32; i++) {\r
+ sm[32 + i] = d[32 + i]\r
+ }\r
\r
this.crypto_hash(r, sm.subarray(32), n + 32)\r
this.reduce(r)\r
this.scalarbase(p, r)\r
this.pack(sm, p)\r
\r
- for (let i = 0; i < 32; i++) sm[i + 32] = pk[i]\r
+ for (let i = 0; i < 32; i++) {\r
+ sm[i + 32] = pk[i]\r
+ }\r
this.crypto_hash(h, sm, n + 64)\r
this.reduce(h)\r
\r
- for (let i = 0; i < 64; i++) x[i] = 0\r
- for (let i = 0; i < 32; i++) x[i] = r[i]\r
+ for (let i = 0; i < 64; i++) {\r
+ x[i] = 0\r
+ }\r
+ for (let i = 0; i < 32; i++) {\r
+ x[i] = r[i]\r
+ }\r
for (let i = 0; i < 32; i++) {\r
for (let j = 0; j < 32; j++) {\r
x[i + j] += h[i] * d[j]\r
\r
if (this.unpackneg(q, pk)) return -1\r
\r
- for (let i = 0; i < n; i++) m[i] = sm[i]\r
- for (let i = 0; i < 32; i++) m[i + 32] = pk[i]\r
+ for (let i = 0; i < n; i++) {\r
+ m[i] = sm[i]\r
+ }\r
+ for (let i = 0; i < 32; i++) {\r
+ m[i + 32] = pk[i]\r
+ }\r
this.crypto_hash(h, m, n)\r
this.reduce(h)\r
this.scalarmult(p, q, h)\r
\r
n -= 64\r
if (this.crypto_verify_32(sm, 0, t, 0)) {\r
- for (let i = 0; i < n; i++) m[i] = 0\r
+ for (let i = 0; i < n; i++) {\r
+ m[i] = 0\r
+ }\r
return -1\r
}\r
\r
- for (let i = 0; i < n; i++) m[i] = sm[i + 64]\r
+ for (let i = 0; i < n; i++) {\r
+ m[i] = sm[i + 64]\r
+ }\r
return n\r
}\r
\r
- static crypto_sign_BYTES = 64\r
- static crypto_sign_PUBLICKEYBYTES = 32\r
- static crypto_sign_SECRETKEYBYTES = 32\r
- static crypto_sign_SEEDBYTES = 32\r
+ static crypto_sign_BYTES: 64 = 64\r
+ static crypto_sign_PUBLICKEYBYTES: 32 = 32\r
+ static crypto_sign_SECRETKEYBYTES: 32 = 32\r
+ static crypto_sign_SEEDBYTES: 32 = 32\r
\r
/* High-level API */\r
-\r
static checkArrayTypes (...args: Uint8Array[]): void {\r
for (let i = 0; i < args.length; i++) {\r
- if (!(args[i] instanceof Uint8Array))\r
- throw new TypeError(`expected Uint8Array; received ${args[i].constructor?.name ?? typeof args[i]}`)\r
+ if (!(args[i] instanceof Uint8Array)) {\r
+ throw new TypeError(`expected Uint8Array; actual ${args[i].constructor?.name ?? typeof args[i]}`)\r
+ }\r
}\r
}\r
\r
static hexify (buf: Uint8Array): string {\r
let str = ''\r
for (let i = 0; i < buf.length; i++) {\r
- if (typeof buf[i] !== 'number')\r
+ if (typeof buf[i] !== 'number') {\r
throw new TypeError(`expected number to convert to hex; received ${typeof buf[i]}`)\r
- if (buf[i] < 0 || buf[i] > 255)\r
+ }\r
+ if (buf[i] < 0 || buf[i] > 255) {\r
throw new RangeError(`expected byte value 0-255; received ${buf[i]}`)\r
+ }\r
str += buf[i].toString(16).padStart(2, '0')\r
}\r
return str\r
\r
static sign (msg: Uint8Array, secretKey: Uint8Array): Uint8Array {\r
this.checkArrayTypes(msg, secretKey)\r
- if (secretKey.length !== this.crypto_sign_SECRETKEYBYTES)\r
- throw new Error('bad secret key size')\r
- var signedMsg = new Uint8Array(this.crypto_sign_BYTES + msg.length)\r
+ if (secretKey.byteLength !== this.crypto_sign_SECRETKEYBYTES) {\r
+ throw new Error(`expected key size ${this.crypto_sign_SECRETKEYBYTES} bytes; actual key size ${secretKey.byteLength} bytes`)\r
+ }\r
+ const signedMsg = new Uint8Array(this.crypto_sign_BYTES + msg.length)\r
const publicKey = this.parseHex(this.convert(secretKey))\r
this.crypto_sign(signedMsg, msg, msg.length, secretKey, publicKey)\r
return signedMsg\r
\r
static open (signedMsg: Uint8Array, publicKey: Uint8Array): Uint8Array {\r
this.checkArrayTypes(signedMsg, publicKey)\r
- if (publicKey.length !== this.crypto_sign_PUBLICKEYBYTES)\r
+ if (publicKey.length !== this.crypto_sign_PUBLICKEYBYTES) {\r
throw new Error('bad public key size')\r
+ }\r
const tmp = new Uint8Array(signedMsg.length)\r
- var mlen = this.crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey)\r
+ const mlen = this.crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey)\r
\r
if (mlen < 0) return new Uint8Array(0)\r
\r
- var m = new Uint8Array(mlen)\r
- for (var i = 0; i < m.length; i++) m[i] = tmp[i]\r
+ const m = new Uint8Array(mlen)\r
+ for (let i = 0; i < m.length; i++) {\r
+ m[i] = tmp[i]\r
+ }\r
return m\r
}\r
\r
static detached (msg: Uint8Array, secretKey: Uint8Array): string {\r
- var signedMsg = this.sign(msg, secretKey)\r
- var sig = new Uint8Array(this.crypto_sign_BYTES)\r
- for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i]\r
+ const signedMsg = this.sign(msg, secretKey)\r
+ const sig = new Uint8Array(this.crypto_sign_BYTES)\r
+ for (let i = 0; i < sig.length; i++) {\r
+ sig[i] = signedMsg[i]\r
+ }\r
return this.hexify(sig).toUpperCase()\r
}\r
\r
static verify (msg: Uint8Array, sig: Uint8Array, publicKey: Uint8Array): boolean {\r
this.checkArrayTypes(msg, sig, publicKey)\r
- if (sig.length !== this.crypto_sign_BYTES)\r
+ if (sig.length !== this.crypto_sign_BYTES) {\r
throw new Error('bad signature size')\r
- if (publicKey.length !== this.crypto_sign_PUBLICKEYBYTES)\r
+ }\r
+ if (publicKey.length !== this.crypto_sign_PUBLICKEYBYTES) {\r
throw new Error('bad public key size')\r
+ }\r
const sm = new Uint8Array(this.crypto_sign_BYTES + msg.length)\r
const m = new Uint8Array(this.crypto_sign_BYTES + msg.length)\r
- for (let i = 0; i < this.crypto_sign_BYTES; i++) sm[i] = sig[i]\r
- for (let i = 0; i < msg.length; i++) sm[i + this.crypto_sign_BYTES] = msg[i]\r
+ for (let i = 0; i < this.crypto_sign_BYTES; i++) {\r
+ sm[i] = sig[i]\r
+ }\r
+ for (let i = 0; i < msg.length; i++) {\r
+ sm[i + this.crypto_sign_BYTES] = msg[i]\r
+ }\r
return (this.crypto_sign_open(m, sm, sm.length, publicKey) >= 0)\r
}\r
\r
static convert (seed: string | Uint8Array): string {\r
if (typeof seed === 'string') seed = this.parseHex(seed)\r
this.checkArrayTypes(seed)\r
- if (seed.length !== this.crypto_sign_SEEDBYTES)\r
+ if (seed.length !== this.crypto_sign_SEEDBYTES) {\r
throw new Error('bad seed size')\r
-\r
+ }\r
const pk = new Uint8Array(this.crypto_sign_PUBLICKEYBYTES)\r
const p: Float64Array[] = [this.gf(), this.gf(), this.gf(), this.gf()]\r
\r
+++ /dev/null
-// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
-// SPDX-License-Identifier: GPL-3.0-or-later
-// Based on nano-webgl-pow by Ben Green (numtel) <ben@latenightsketches.com>
-// https://github.com/numtel/nano-webgl-pow
-import { WorkerInterface } from '../pool.js'
-
-export class Pow extends WorkerInterface {
- static {
- Pow.listen()
- }
- /**
- * Calculates proof-of-work as described by the Nano cryptocurrency protocol.
- *
- * @param {any[]} data - Array of hashes and minimum thresholds
- * @returns Promise for proof-of-work attached to original array objects
- */
- static async work (data: any[]): Promise<any[]> {
- return new Promise(async (resolve, reject): Promise<void> => {
- for (const d of data) {
- try {
- d.work = await this.find(d.hash, d.threshold)
- } catch (err) {
- reject(err)
- }
- }
- resolve(data)
- })
- }
-
- /**
- * Finds a nonce that satisfies the Nano proof-of-work requirements.
- *
- * @param {string} hashHex - Hexadecimal hash of previous block, or public key for new accounts
- * @param {number} [threshold=0xfffffff8] - Difficulty of proof-of-work calculation
- */
- static async find (hash: string, threshold: number = 0xfffffff8): Promise<string> {
- return new Promise<string>(resolve => {
- this.#calculate(hash, resolve, threshold)
- })
- }
-
- // Vertex Shader
- static #vsSource = `#version 300 es
-#pragma vscode_glsllint_stage: vert
-precision highp float;
-layout (location=0) in vec4 position;
-layout (location=1) in vec2 uv;
-
-out vec2 uv_pos;
-
-void main() {
- uv_pos = uv;
- gl_Position = position;
-}`
-
- // Fragment shader
- static #fsSource = `#version 300 es
-#pragma vscode_glsllint_stage: frag
-precision highp float;
-precision highp int;
-
-in vec2 uv_pos;
-out vec4 fragColor;
-
-// blockhash - array of precalculated block hash components
-// threshold - 0xfffffff8 for send/change blocks, 0xfffffe00 for all else
-// workload - Defines canvas size
-layout(std140) uniform UBO {
- uint blockhash[8];
- uint threshold;
- float workload;
-};
-
-// Random work values
-// First 2 bytes will be overwritten by texture pixel position
-// Second 2 bytes will be modified if the canvas size is greater than 256x256
-// Last 4 bytes remain as generated externally
-layout(std140) uniform WORK {
- uvec4 work[2];
-};
-
-// Defined separately from uint v[32] below as the original value is required
-// to calculate the second uint32 of the digest for threshold comparison
-#define BLAKE2B_IV32_1 0x6A09E667u
-
-// Both buffers represent 16 uint64s as 32 uint32s
-// because that's what GLSL offers, just like Javascript
-
-// Compression buffer, intialized to 2 instances of the initialization vector
-// The following values have been modified from the BLAKE2B_IV:
-// OUTLEN is constant 8 bytes
-// v[0] ^= 0x01010000u ^ uint(OUTLEN);
-// INLEN is constant 40 bytes: work value (8) + block hash (32)
-// v[24] ^= uint(INLEN);
-// It's always the "last" compression at this INLEN
-// v[28] = ~v[28];
-// v[29] = ~v[29];
-uint v[32] = uint[32](
- 0xF2BDC900u, 0x6A09E667u, 0x84CAA73Bu, 0xBB67AE85u,
- 0xFE94F82Bu, 0x3C6EF372u, 0x5F1D36F1u, 0xA54FF53Au,
- 0xADE682D1u, 0x510E527Fu, 0x2B3E6C1Fu, 0x9B05688Cu,
- 0xFB41BD6Bu, 0x1F83D9ABu, 0x137E2179u, 0x5BE0CD19u,
- 0xF3BCC908u, 0x6A09E667u, 0x84CAA73Bu, 0xBB67AE85u,
- 0xFE94F82Bu, 0x3C6EF372u, 0x5F1D36F1u, 0xA54FF53Au,
- 0xADE682F9u, 0x510E527Fu, 0x2B3E6C1Fu, 0x9B05688Cu,
- 0x04BE4294u, 0xE07C2654u, 0x137E2179u, 0x5BE0CD19u
-);
-// Input data buffer
-uint m[32];
-
-// These are offsets into the input data buffer for each mixing step.
-// They are multiplied by 2 from the original SIGMA values in
-// the C reference implementation, which refered to uint64s.
-const int SIGMA82[192] = int[192](
- 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,
- 28,20,8,16,18,30,26,12,2,24,0,4,22,14,10,6,
- 22,16,24,0,10,4,30,26,20,28,6,12,14,2,18,8,
- 14,18,6,2,26,24,22,28,4,12,10,20,8,0,30,16,
- 18,0,10,14,4,8,20,30,28,2,22,24,12,16,6,26,
- 4,24,12,20,0,22,16,6,8,26,14,10,30,28,2,18,
- 24,10,2,30,28,26,8,20,0,14,12,6,18,4,16,22,
- 26,22,14,28,24,2,6,18,10,0,30,8,16,12,4,20,
- 12,30,28,18,22,6,0,16,24,4,26,14,2,8,20,10,
- 20,4,16,8,14,12,2,10,30,22,18,28,6,24,26,0,
- 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,
- 28,20,8,16,18,30,26,12,2,24,0,4,22,14,10,6
-);
-
-// 64-bit unsigned addition within the compression buffer
-// Sets v[a,a+1] += b
-// b0 is the low 32 bits of b, b1 represents the high 32 bits
-void add_uint64 (int a, uint b0, uint b1) {
- uint o0 = v[a] + b0;
- uint o1 = v[a + 1] + b1;
- if (v[a] > 0xFFFFFFFFu - b0) { // did low 32 bits overflow?
- o1++;
- }
- v[a] = o0;
- v[a + 1] = o1;
-}
-
-// G Mixing function
-void B2B_G (int a, int b, int c, int d, int ix, int iy) {
- add_uint64(a, v[b], v[b+1]);
- add_uint64(a, m[ix], m[ix + 1]);
-
- // v[d,d+1] = (v[d,d+1] xor v[a,a+1]) rotated to the right by 32 bits
- uint xor0 = v[d] ^ v[a];
- uint xor1 = v[d + 1] ^ v[a + 1];
- v[d] = xor1;
- v[d + 1] = xor0;
-
- add_uint64(c, v[d], v[d+1]);
-
- // v[b,b+1] = (v[b,b+1] xor v[c,c+1]) rotated right by 24 bits
- xor0 = v[b] ^ v[c];
- xor1 = v[b + 1] ^ v[c + 1];
- v[b] = (xor0 >> 24) ^ (xor1 << 8);
- v[b + 1] = (xor1 >> 24) ^ (xor0 << 8);
-
- add_uint64(a, v[b], v[b+1]);
- add_uint64(a, m[iy], m[iy + 1]);
-
- // v[d,d+1] = (v[d,d+1] xor v[a,a+1]) rotated right by 16 bits
- xor0 = v[d] ^ v[a];
- xor1 = v[d + 1] ^ v[a + 1];
- v[d] = (xor0 >> 16) ^ (xor1 << 16);
- v[d + 1] = (xor1 >> 16) ^ (xor0 << 16);
-
- add_uint64(c, v[d], v[d+1]);
-
- // v[b,b+1] = (v[b,b+1] xor v[c,c+1]) rotated right by 63 bits
- xor0 = v[b] ^ v[c];
- xor1 = v[b + 1] ^ v[c + 1];
- v[b] = (xor1 >> 31) ^ (xor0 << 1);
- v[b + 1] = (xor0 >> 31) ^ (xor1 << 1);
-}
-
-void main() {
- int i;
- uvec4 u_work0 = work[0];
- uvec4 u_work1 = work[1];
- uint uv_x = uint(uv_pos.x * workload);
- uint uv_y = uint(uv_pos.y * workload);
- uint x_pos = uv_x % 256u;
- uint y_pos = uv_y % 256u;
- uint x_index = (uv_x - x_pos) / 256u;
- uint y_index = (uv_y - y_pos) / 256u;
-
- // First 2 work bytes are the x,y pos within the 256x256 area, the next
- // two bytes are modified from the random generated value, XOR'd with
- // the x,y area index of where this pixel is located
- m[0] = (x_pos ^ (y_pos << 8) ^ ((u_work0.b ^ x_index) << 16) ^ ((u_work0.a ^ y_index) << 24));
-
- // Remaining bytes are un-modified from the random generated value
- m[1] = (u_work1.r ^ (u_work1.g << 8) ^ (u_work1.b << 16) ^ (u_work1.a << 24));
-
- // Block hash
- for (i=0;i<8;i++) {
- m[i+2] = blockhash[i];
- }
-
- // twelve rounds of mixing
- for(i=0;i<12;i++) {
- B2B_G(0, 8, 16, 24, SIGMA82[i * 16 + 0], SIGMA82[i * 16 + 1]);
- B2B_G(2, 10, 18, 26, SIGMA82[i * 16 + 2], SIGMA82[i * 16 + 3]);
- B2B_G(4, 12, 20, 28, SIGMA82[i * 16 + 4], SIGMA82[i * 16 + 5]);
- B2B_G(6, 14, 22, 30, SIGMA82[i * 16 + 6], SIGMA82[i * 16 + 7]);
- B2B_G(0, 10, 20, 30, SIGMA82[i * 16 + 8], SIGMA82[i * 16 + 9]);
- B2B_G(2, 12, 22, 24, SIGMA82[i * 16 + 10], SIGMA82[i * 16 + 11]);
- B2B_G(4, 14, 16, 26, SIGMA82[i * 16 + 12], SIGMA82[i * 16 + 13]);
- B2B_G(6, 8, 18, 28, SIGMA82[i * 16 + 14], SIGMA82[i * 16 + 15]);
- }
-
- // Pixel data is multipled by threshold test result (0 or 1)
- // First 4 bytes insignificant, only calculate digest of second 4 bytes
- if ((BLAKE2B_IV32_1 ^ v[1] ^ v[17]) > threshold) {
- fragColor = vec4(
- float(x_index + 1u)/255., // +1 to distinguish from 0 (unsuccessful) pixels
- float(y_index + 1u)/255., // Same as previous
- float(x_pos)/255., // Return the 2 custom bytes used in work value
- float(y_pos)/255. // Second custom byte
- );
- } else {
- discard;
- }
-}`
-
- /** Used to set canvas size. Must be a multiple of 256. */
- static #WORKLOAD: number = 256 * Math.max(1, Math.floor(navigator.hardwareConcurrency))
-
- static #hexify (arr: number[] | Uint8Array): string {
- let out = ''
- for (let i = arr.length - 1; i >= 0; i--) {
- out += arr[i].toString(16).padStart(2, '0')
- }
- return out
- }
-
- static #gl: WebGL2RenderingContext | null
- static #program: WebGLProgram | null
- static #vertexShader: WebGLShader | null
- static #fragmentShader: WebGLShader | null
- static #positionBuffer: WebGLBuffer | null
- static #uvBuffer: WebGLBuffer | null
- static #uboBuffer: WebGLBuffer | null
- static #workBuffer: WebGLBuffer | null
- static #query: WebGLQuery | null
- static #pixels: Uint8Array
- // Vertex Positions, 2 triangles
- static #positions = new Float32Array([
- -1, -1, 0, -1, 1, 0, 1, 1, 0,
- 1, -1, 0, 1, 1, 0, -1, -1, 0
- ])
- // Texture Positions
- static #uvPosArray = new Float32Array([
- 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1
- ])
-
- // Compile
- static {
- this.#gl = new OffscreenCanvas(this.#WORKLOAD, this.#WORKLOAD).getContext('webgl2')
- if (this.#gl == null) throw new Error('WebGL 2 is required')
- this.#gl.clearColor(0, 0, 0, 1)
-
- this.#program = this.#gl.createProgram()
- if (this.#program == null) throw new Error('Failed to create shader program')
-
- this.#vertexShader = this.#gl.createShader(this.#gl.VERTEX_SHADER)
- if (this.#vertexShader == null) throw new Error('Failed to create vertex shader')
- this.#gl.shaderSource(this.#vertexShader, this.#vsSource)
- this.#gl.compileShader(this.#vertexShader)
- if (!this.#gl.getShaderParameter(this.#vertexShader, this.#gl.COMPILE_STATUS))
- throw new Error(this.#gl.getShaderInfoLog(this.#vertexShader) ?? `Failed to compile vertex shader`)
-
- this.#fragmentShader = this.#gl.createShader(this.#gl.FRAGMENT_SHADER)
- if (this.#fragmentShader == null) throw new Error('Failed to create fragment shader')
- this.#gl.shaderSource(this.#fragmentShader, this.#fsSource)
- this.#gl.compileShader(this.#fragmentShader)
- if (!this.#gl.getShaderParameter(this.#fragmentShader, this.#gl.COMPILE_STATUS))
- throw new Error(this.#gl.getShaderInfoLog(this.#fragmentShader) ?? `Failed to compile fragment shader`)
-
- this.#gl.attachShader(this.#program, this.#vertexShader)
- this.#gl.attachShader(this.#program, this.#fragmentShader)
- this.#gl.linkProgram(this.#program)
- if (!this.#gl.getProgramParameter(this.#program, this.#gl.LINK_STATUS))
- throw new Error(this.#gl.getProgramInfoLog(this.#program) ?? `Failed to link program`)
-
- // Construct simple 2D geometry
- this.#gl.useProgram(this.#program)
- const triangleArray = this.#gl.createVertexArray()
- this.#gl.bindVertexArray(triangleArray)
-
- this.#positionBuffer = this.#gl.createBuffer()
- this.#gl.bindBuffer(this.#gl.ARRAY_BUFFER, this.#positionBuffer)
- this.#gl.bufferData(this.#gl.ARRAY_BUFFER, this.#positions, this.#gl.STATIC_DRAW)
- this.#gl.vertexAttribPointer(0, 3, this.#gl.FLOAT, false, 0, 0)
- this.#gl.enableVertexAttribArray(0)
-
- this.#uvBuffer = this.#gl.createBuffer()
- this.#gl.bindBuffer(this.#gl.ARRAY_BUFFER, this.#uvBuffer)
- this.#gl.bufferData(this.#gl.ARRAY_BUFFER, this.#uvPosArray, this.#gl.STATIC_DRAW)
- this.#gl.vertexAttribPointer(1, 2, this.#gl.FLOAT, false, 0, 0)
- this.#gl.enableVertexAttribArray(1)
-
- this.#uboBuffer = this.#gl.createBuffer()
- this.#gl.bindBuffer(this.#gl.UNIFORM_BUFFER, this.#uboBuffer)
- this.#gl.bufferData(this.#gl.UNIFORM_BUFFER, 144, this.#gl.DYNAMIC_DRAW)
- this.#gl.bindBuffer(this.#gl.UNIFORM_BUFFER, null)
- this.#gl.bindBufferBase(this.#gl.UNIFORM_BUFFER, 0, this.#uboBuffer)
- this.#gl.uniformBlockBinding(this.#program, this.#gl.getUniformBlockIndex(this.#program, 'UBO'), 0)
-
- this.#workBuffer = this.#gl.createBuffer()
- this.#gl.bindBuffer(this.#gl.UNIFORM_BUFFER, this.#workBuffer)
- this.#gl.bufferData(this.#gl.UNIFORM_BUFFER, 32, this.#gl.STREAM_DRAW)
- this.#gl.bindBuffer(this.#gl.UNIFORM_BUFFER, null)
- this.#gl.bindBufferBase(this.#gl.UNIFORM_BUFFER, 1, this.#workBuffer)
- this.#gl.uniformBlockBinding(this.#program, this.#gl.getUniformBlockIndex(this.#program, 'WORK'), 1)
-
- this.#pixels = new Uint8Array(this.#gl.drawingBufferWidth * this.#gl.drawingBufferHeight * 4)
- this.#query = this.#gl.createQuery()
- }
-
- static #calculate (hashHex: string, callback: (nonce: string | PromiseLike<string>) => any, threshold: number): void {
- if (Pow.#gl == null) throw new Error('WebGL 2 is required')
- if (!/^[A-F-a-f0-9]{64}$/.test(hashHex)) throw new Error(`invalid_hash ${hashHex}`)
- if (typeof threshold !== 'number') throw new TypeError(`Invalid threshold ${threshold}`)
- if (this.#gl == null) throw new Error('WebGL 2 is required')
-
- // Set up uniform buffer object
- const uboView = new DataView(new ArrayBuffer(144))
- for (let i = 0; i < 64; i += 8) {
- const uint32 = hashHex.slice(i, i + 8)
- uboView.setUint32(i * 2, parseInt(uint32, 16))
- }
- uboView.setUint32(128, threshold, true)
- uboView.setFloat32(132, Pow.#WORKLOAD - 1, true)
- Pow.#gl.bindBuffer(Pow.#gl.UNIFORM_BUFFER, Pow.#uboBuffer)
- Pow.#gl.bufferSubData(Pow.#gl.UNIFORM_BUFFER, 0, uboView)
- Pow.#gl.bindBuffer(Pow.#gl.UNIFORM_BUFFER, null)
-
- // Draw output until success or progressCallback says to stop
- const work = new Uint8Array(8)
- const draw = (): void => {
- if (Pow.#gl == null) throw new Error('WebGL 2 is required')
- if (Pow.#query == null) throw new Error('WebGL 2 is required to run queries')
- Pow.#gl.clear(Pow.#gl.COLOR_BUFFER_BIT)
-
- // Upload work buffer
- crypto.getRandomValues(work)
- Pow.#gl.bindBuffer(Pow.#gl.UNIFORM_BUFFER, Pow.#workBuffer)
- Pow.#gl.bufferSubData(Pow.#gl.UNIFORM_BUFFER, 0, Uint32Array.from(work))
- Pow.#gl.bindBuffer(Pow.#gl.UNIFORM_BUFFER, null)
-
- Pow.#gl.beginQuery(Pow.#gl.ANY_SAMPLES_PASSED_CONSERVATIVE, Pow.#query)
- Pow.#gl.drawArrays(Pow.#gl.TRIANGLES, 0, 6)
- Pow.#gl.endQuery(Pow.#gl.ANY_SAMPLES_PASSED_CONSERVATIVE)
-
- requestAnimationFrame(checkQueryResult)
- }
-
- function checkQueryResult () {
- if (Pow.#gl == null) throw new Error('WebGL 2 is required to check query results')
- if (Pow.#query == null) throw new Error('Query not found')
- if (Pow.#gl.getQueryParameter(Pow.#query, Pow.#gl.QUERY_RESULT_AVAILABLE)) {
- const anySamplesPassed = Pow.#gl.getQueryParameter(Pow.#query, Pow.#gl.QUERY_RESULT)
- if (anySamplesPassed) {
- // A valid nonce was found
- readBackResult()
- } else {
- // No valid nonce found, start the next draw call
- requestAnimationFrame(draw)
- }
- } else {
- // Query result not yet available, check again in the next frame
- requestAnimationFrame(checkQueryResult)
- }
- }
- function readBackResult () {
- if (Pow.#gl == null) throw new Error('WebGL 2 is required to check read results')
- Pow.#gl.readPixels(0, 0, Pow.#gl.drawingBufferWidth, Pow.#gl.drawingBufferHeight, Pow.#gl.RGBA, Pow.#gl.UNSIGNED_BYTE, Pow.#pixels)
- // Check the pixels for any success
- for (let i = 0; i < Pow.#pixels.length; i += 4) {
- if (Pow.#pixels[i] !== 0) {
- const hex = Pow.#hexify(work.subarray(4, 8)) + Pow.#hexify([
- Pow.#pixels[i + 2],
- Pow.#pixels[i + 3],
- work[2] ^ (Pow.#pixels[i] - 1),
- work[3] ^ (Pow.#pixels[i + 1] - 1)
- ])
- // Return the work value with the custom bits
- typeof callback === 'function' && callback(hex)
- return
- }
- }
- }
- draw()
- }
-}
-
-export default `
- const WorkerInterface = ${WorkerInterface}
- const Pow = ${Pow}
-`
// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
// SPDX-License-Identifier: GPL-3.0-or-later
-import { Account } from './lib/account.js'
-import { Blake2b } from './lib/blake2b.js'
-import { SendBlock, ReceiveBlock, ChangeBlock } from './lib/block.js'
-import { Pow } from './lib/workers/powgl.js'
-import { Rpc } from './lib/rpc.js'
-import { Rolodex } from './lib/rolodex.js'
-import { Safe } from './lib/safe.js'
-import { Tools } from './lib/tools.js'
-import { Bip44Wallet, Blake2bWallet, LedgerWallet } from './lib/wallet.js'
+import { Account } from './lib/account'
+import { Blake2b } from './lib/blake2b'
+import { SendBlock, ReceiveBlock, ChangeBlock } from './lib/block'
+import { Rolodex } from './lib/rolodex'
+import { Rpc } from './lib/rpc'
+import { Safe } from './lib/safe'
+import { Tools } from './lib/tools'
+import { Bip44Wallet, Blake2bWallet, LedgerWallet } from './lib/wallet'
-export { Account, Blake2b, SendBlock, ReceiveBlock, ChangeBlock, Pow, Rpc, Rolodex, Safe, Tools, Bip44Wallet, Blake2bWallet, LedgerWallet }
+export { Account, Blake2b, SendBlock, ReceiveBlock, ChangeBlock, Rpc, Rolodex, Safe, Tools, Bip44Wallet, Blake2bWallet, LedgerWallet }
+++ /dev/null
-<!DOCTYPE html>
-
-<head>
- <link rel="icon" href="./favicon.ico">
- <script type="module" src="./dist/test.min.js"></script>
- <style>body{background:black;}</style>
-</head>
-
-<body></body>
-
-</html>
// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
// SPDX-License-Identifier: GPL-3.0-or-later
+import { Queue } from './QUEUE.mjs'
+
+const queue = new Queue()
+
if (globalThis.sessionStorage == null) {
let _sessionStorage = {}
Object.defineProperty(globalThis, 'sessionStorage', {
})
}
-export function average (times) {
- let sum = 0, reciprocals = 0, product = 1, count = times.length
+export function stats (times) {
+ if (times == null || times.length === 0) return null
+
+ const count = times.length
+ const truncatedStart = Math.floor(count * 0.1)
+ const truncatedEnd = count - truncatedStart
+ const truncatedCount = truncatedEnd - truncatedStart
+ let min = Number.MAX_SAFE_INTEGER
+ let logarithms, max, median, reciprocals, total
+ logarithms = max = median = reciprocals = total = 0
+
+ let truncatedMin = Number.MAX_SAFE_INTEGER
+ let truncatedLogarithms, truncatedMax, truncatedReciprocals, truncatedTotal
+ truncatedLogarithms = truncatedMax = truncatedReciprocals = truncatedTotal = 0
+
+ times.sort((a, b) => a - b)
for (let i = 0; i < count; i++) {
- sum += times[i]
- reciprocals += 1 / times[i]
- product *= times[i]
+ const time = times[i]
+ total += time
+ logarithms += Math.log(time)
+ reciprocals += 1 / time
+ min = Math.min(min, time)
+ max = Math.max(max, time)
+ if (i === Math.floor((count - 1) / 2)) median = time
+ if (i === Math.floor(count / 2) && count % 2 === 0) median = (median + time) / 2
+ }
+ for (let i = truncatedStart; i < truncatedEnd; i++) {
+ const time = times[i]
+ truncatedTotal += time
+ truncatedLogarithms += Math.log(time)
+ truncatedReciprocals += 1 / time
+ truncatedMin = Math.min(truncatedMin, time)
+ truncatedMax = Math.max(truncatedMax, time)
}
return {
- total: sum,
- arithmetic: sum / count,
+ count,
+ total,
+ rate: 1000 * count / total,
+ min,
+ max,
+ median,
+ arithmetic: total / count,
+ geometric: Math.exp(logarithms / count),
harmonic: count / reciprocals,
- geometric: Math.pow(product, 1 / count)
+ truncatedCount,
+ truncatedTotal,
+ truncatedRate: 1000 * truncatedCount / truncatedTotal,
+ truncatedMin,
+ truncatedMax,
+ truncatedArithmetic: truncatedTotal / truncatedCount,
+ truncatedGeometric: Math.exp(truncatedLogarithms / truncatedCount),
+ truncatedHarmonic: truncatedCount / truncatedReciprocals,
}
}
console.log(`%cPASS `, 'color:green', ...args)
}
-
-/**
-* Who watches the watchers?
-*/
await suite('TEST RUNNER CHECK', async () => {
+
console.assert(failures.length === 0)
console.assert(passes.length === 0)
console.log(`%cTEST RUNNER CHECK DONE`, 'font-weight:bold')
})
-export function skip (name, fn) {
- return new Promise(resolve => {
- console.log(`%cSKIP `, 'color:blue', name)
- resolve(null)
- })
-}
-
-export function suite (name, fn) {
- if (fn.constructor.name === 'AsyncFunction') fn = fn()
- if (typeof fn === 'function') fn = new Promise(resolve => resolve(fn()))
- return new Promise(async (resolve) => {
+export function suite (name, opts, fn) {
+ if (fn === undefined) fn = opts
+ return queue.add(async () => {
+ if (opts?.skip) {
+ console.group(`%cSKIP `, 'color:CornflowerBlue', name)
+ console.groupEnd()
+ return
+ }
+ if (fn.constructor.name === 'AsyncFunction') fn = fn()
+ if (typeof fn === 'function') fn = new Promise(resolve => resolve(fn()))
console.group(`%c${name}`, 'font-weight:bold')
await fn
console.groupEnd()
- resolve(null)
})
}
-export function test (name, fn) {
+export function test (name, opts, fn) {
+ if (opts?.skip) return console.log(`%cSKIP `, 'color:CornflowerBlue', name)
+ if (fn === undefined) fn = opts
if (fn instanceof Promise) {
try {
return fn
return a !== b
},
rejects: async (fn, msg) => {
+ if (fn.constructor.name === 'AsyncFunction') {
+ fn = fn()
+ }
if (fn instanceof Promise) {
try {
- fn.then(() => { throw new Error(msg ?? 'expected async function to reject') })
- .catch((err) => { return true })
- } catch (err) {
- return true
- }
- } else if (fn.constructor.name === 'AsyncFunction') {
- try {
- fn.then(() => { throw new Error(msg ?? 'expected async function to reject') })
- .catch((err) => { return true })
+ await fn
+ throw new Error(msg ?? 'expected async function to reject')
} catch (err) {
return true
}
}
},
resolves: async (fn, msg) => {
+ if (fn.constructor.name === 'AsyncFunction') {
+ fn = fn()
+ }
if (fn instanceof Promise) {
try {
- fn.then(() => { return true })
- .catch((err) => { throw new Error(msg ?? 'expected async function to resolve') })
- return true
- } catch (err) {
- throw new Error(msg ?? 'expected async function to resolve')
- }
- } else if (fn.constructor.name === 'AsyncFunction') {
- try {
- fn().then(() => { return true })
- .catch((err) => { throw new Error(msg ?? 'expected async function to resolve') })
+ await fn
return true
} catch (err) {
throw new Error(msg ?? 'expected async function to resolve')
--- /dev/null
+//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
+//! SPDX-License-Identifier: GPL-3.0-or-later
+
+/**
+ * Serially executes asynchronous functions.
+ */
+export class Queue {
+ #isIdle
+ #queue
+
+ constructor () {
+ this.#isIdle = true
+ this.#queue = []
+ }
+
+ #process = () => {
+ const { task, resolve, reject, args } = this.#queue.shift() ?? {}
+ this.#isIdle = !task
+ task?.(...args).then(resolve).catch(reject).finally(this.#process)
+ }
+
+ async add (task, ...args) {
+ if (typeof task !== 'function') throw new TypeError('task is not a function')
+ return new Promise((resolve, reject) => {
+ this.#queue.push({ task, resolve, reject, args })
+ if (this.#isIdle) this.#process()
+ })
+ }
+
+ async prioritize (task, ...args) {
+ if (typeof task !== 'function') throw new TypeError('task is not a function')
+ return new Promise((resolve, reject) => {
+ if (typeof task !== 'function') reject('task is not a function')
+ this.#queue.unshift({ task, resolve, reject, args })
+ if (this.#isIdle) this.#process()
+ })
+ }
+}
+++ /dev/null
-// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-/**
-* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
-*
-* Do not send any funds to the test vectors below!
-*
-* Sources:
-* https://docs.nano.org/integration-guides/key-management/#test-vectors
-* https://docs.nano.org/integration-guides/key-management/#creating-transactions
-* https://github.com/trezor/python-mnemonic/blob/master/vectors.json
-* https://tools.nanos.cc/?tool=seed
-*/
-export const GENESIS_ADDRESS = 'nano_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3'
-export const RAW_MAX = '340282366920938463463374607431768211455'
-export const SUPPLY_MAX = '133248297920938463463374607431768211455'
-
-export const NANO_TEST_VECTORS = Object.freeze({
- MNEMONIC: 'edge defense waste choose enrich upon flee junk siren film clown finish luggage leader kid quick brick print evidence swap drill paddle truly occur',
- PASSWORD: 'some password',
- BIP39_SEED: '0DC285FDE768F7FF29B66CE7252D56ED92FE003B605907F7A4F683C3DC8586D34A914D3C71FC099BB38EE4A59E5B081A3497B7A323E90CC68F67B5837690310C',
-
- PRIVATE_0: '3BE4FC2EF3F3B7374E6FC4FB6E7BB153F8A2998B3B3DAB50853EABE128024143',
- PUBLIC_0: '5B65B0E8173EE0802C2C3E6C9080D1A16B06DE1176C938A924F58670904E82C4',
- ADDRESS_0: 'nano_1pu7p5n3ghq1i1p4rhmek41f5add1uh34xpb94nkbxe8g4a6x1p69emk8y1d',
-
- PRIVATE_1: 'CE7E429E683D652446261C17A96DA9ED1897AEA96C8046F2B8036F6B05CB1A83',
- PUBLIC_1: 'D9F7762E9CD4E7ED632481308CDB8F54ABF0241332C0A8641F61E92E2FB03C12',
- ADDRESS_1: 'nano_3phqgrqbso99xojkb1bijmfryo7dy1k38ep1o3k3yrhb7rqu1h1k47yu78gz',
-
- PRIVATE_2: '1257DF74609B9C6461A3F4E7FD6E3278F2DDCF2562694F2C3AA0515AF4F09E38',
- PUBLIC_2: 'A46DA51986E25A14D82E32D765DCEE69B9EECCD4405411430D91DDB61B717566',
- ADDRESS_2: 'nano_3b5fnnerfrkt4me4wepqeqggwtfsxu8fai4n473iu6gxprfq4xd8pk9gh1dg',
-
- SEND_BLOCK: {
- account: "nano_1e5aqegc1jb7qe964u4adzmcezyo6o146zb8hm6dft8tkp79za3sxwjym5rx",
- previous: "92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D",
- representative: "nano_1stofnrxuz3cai7ze75o174bpm7scwj9jn3nxsn8ntzg784jf1gzn1jjdkou",
- balance: "11618869000000000000000000000000",
- link: "nano_1q3hqecaw15cjt7thbtxu3pbzr1eihtzzpzxguoc37bj1wc5ffoh7w74gi6p",
- hash: "BB569136FA05F8CBF65CEF2EDE368475B289C4477342976556BA4C0DDF216E45",
- key: "781186FB9EF17DB6E3D1056550D9FAE5D5BBADA6A6BC370E4CBB938B1DC71DA3",
- signature: "74BCC59DBA39A1E34A5F75F96D6DE9154E3477AAD7DE30EA563DFCFE501A804228008F98DDF4A15FD35705102785C50EF76732C3A74B0FEC5B0DD67B574A5900",
- work: "fbffed7c73b61367"
- },
- RECEIVE_BLOCK: {
- account: "nano_1e5aqegc1jb7qe964u4adzmcezyo6o146zb8hm6dft8tkp79za3sxwjym5rx",
- previous: "92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D",
- representative: "nano_1stofnrxuz3cai7ze75o174bpm7scwj9jn3nxsn8ntzg784jf1gzn1jjdkou",
- balance: "11618869000000000000000000000000",
- link: "CBC911F57B6827649423C92C88C0C56637A4274FF019E77E24D61D12B5338783",
- hash: "350D145570578A36D3D5ADE58DC7465F4CAAF257DD55BD93055FF826057E2CDD",
- key: "781186FB9EF17DB6E3D1056550D9FAE5D5BBADA6A6BC370E4CBB938B1DC71DA3",
- signature: "EEFFE1EFCCC8F2F6F2F1B79B80ABE855939DD9D6341323186494ADEE775DAADB3B6A6A07A85511F2185F6E739C4A54F1454436E22255A542ED879FD04FEED001",
- work: "c5cf86de24b24419"
- },
- OPEN_BLOCK: {
- account: "nano_1rawdji18mmcu9psd6h87qath4ta7iqfy8i4rqi89sfdwtbcxn57jm9k3q11",
- previous: "0000000000000000000000000000000000000000000000000000000000000000",
- representative: "nano_1stofnrxuz3cai7ze75o174bpm7scwj9jn3nxsn8ntzg784jf1gzn1jjdkou",
- balance: "100",
- link: "5B2DA492506339C0459867AA1DA1E7EDAAC4344342FAB0848F43B46D248C8E99",
- hash: "ED3BE5340CC9D62964B5A5F84375A06078CBEDC45FB5FA2926985D6E27D803BB",
- key: "0ED82E6990A16E7AD2375AB5D54BEAABF6C676D09BEC74D9295FCAE35439F694",
- signature: "C4C1D0E25E9E1118F0E139704E9001FF54BDABAB4C3A59DE24510E5B48F269ACBC2F3393DFA46B390CA9C6831074829D91E694B81E8C0C2C9C4FA49A757ECB03",
- work: "08d09dc3405d9441"
- }
-})
-
-export const TREZOR_TEST_VECTORS = Object.freeze({
- PASSWORD: 'TREZOR',
-
- ENTROPY_0: "0000000000000000000000000000000000000000000000000000000000000000",
- MNEMONIC_0: "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
- SEED_0: "bda85446c68413707090a52022edd26a1c9462295029f2e60cd7c4f2bbd3097170af7a4d73245cafa9c3cca8d561a7c3de6f5d4a10be8ed2a5e608d68f92fcc8",
- BIP32_KEY_0: "xprv9s21ZrQH143K32qBagUJAMU2LsHg3ka7jqMcV98Y7gVeVyNStwYS3U7yVVoDZ4btbRNf4h6ibWpY22iRmXq35qgLs79f312g2kj5539ebPM",
- BLAKE2B_PRIVATE_0: "9F0E444C69F77A49BD0BE89DB92C38FE713E0963165CCA12FAF5712D7657120F",
- BLAKE2B_PUBLIC_0: "C008B814A7D269A1FA3C6528B19201A24D797912DB9996FF02A1FF356E45552B",
- BLAKE2B_ADDRESS_0: "nano_3i1aq1cchnmbn9x5rsbap8b15akfh7wj7pwskuzi7ahz8oq6cobd99d4r3b7",
-
- ENTROPY_1: "7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F",
- MNEMONIC_1: "legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title",
- SEED_1: "bc09fca1804f7e69da93c2f2028eb238c227f2e9dda30cd63699232578480a4021b146ad717fbb7e451ce9eb835f43620bf5c514db0f8add49f5d121449d3e87",
- BIP32_KEY_1: "xprv9s21ZrQH143K3Y1sd2XVu9wtqxJRvybCfAetjUrMMco6r3v9qZTBeXiBZkS8JxWbcGJZyio8TrZtm6pkbzG8SYt1sxwNLh3Wx7to5pgiVFU",
- BLAKE2B_1_PRIVATE_0: "C54F9F69B088B554FF494D4CE7D23EB1B13E89D338F219F83BC91F415C3F7F2D",
- BLAKE2B_1_PUBLIC_0: "1573BD1B96ECF80571BF544854026E6A967F065028FBC514B548471DC60B3229",
- BLAKE2B_1_ADDRESS_0: "nano_17dmqnfsfu9r1oruyo4aci38wtnphw571c9urncdck495q51pejbp3c648yo",
- BLAKE2B_1_PRIVATE_1: "1B704560A0A04EAFD81E8D13481370DA458E2BB00C57F3AA00120D80F6A2BB6F",
- BLAKE2B_1_PUBLIC_1: "353288BD57F98A2FC940B4D5A5CE9194EF1598611B00C629E96189320AC7409F",
- BLAKE2B_1_ADDRESS_1: "nano_1fbkj4yohyec7z6n3f8onq9b579h4pe848r1rrnykreb8a7egi6z14nozo43",
-
- ENTROPY_2: "8080808080808080808080808080808080808080808080808080808080808080",
- MNEMONIC_2: "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless",
- SEED_2: "c0c519bd0e91a2ed54357d9d1ebef6f5af218a153624cf4f2da911a0ed8f7a09e2ef61af0aca007096df430022f7a2b6fb91661a9589097069720d015e4e982f",
- BIP32_KEY_2: "xprv9s21ZrQH143K3CSnQNYC3MqAAqHwxeTLhDbhF43A4ss4ciWNmCY9zQGvAKUSqVUf2vPHBTSE1rB2pg4avopqSiLVzXEU8KziNnVPauTqLRo",
- BLAKE2B_2_PRIVATE_0: "554BE953D1E2DAAD0F8CBC2002967FC158E57032A6C4FD107FFEB2ACA518B613",
- BLAKE2B_2_PUBLIC_0: "D85DECD78A303A18CC0D7B65FB384B9C49A7E2EF3666250CBD4F6EC4791513F8",
- BLAKE2B_2_ADDRESS_0: "nano_3p4xxmdrne3t5581tyu7zew6q94bnzjgyfm86n8dtmugrjwjc6zrrci4g1rc",
-
- ENTROPY_3: "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
- MNEMONIC_3: "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote",
- SEED_3: "dd48c104698c30cfe2b6142103248622fb7bb0ff692eebb00089b32d22484e1613912f0a5b694407be899ffd31ed3992c456cdf60f5d4564b8ba3f05a69890ad",
- BIP32_KEY_3: "xprv9s21ZrQH143K2WFF16X85T2QCpndrGwx6GueB72Zf3AHwHJaknRXNF37ZmDrtHrrLSHvbuRejXcnYxoZKvRquTPyp2JiNG3XcjQyzSEgqCB",
- BLAKE2B_3_PRIVATE_0: "F1FD8CBD15A54FABDED17C65C4DD44E1F93AAD122FCC1840B1EDEFAAA5BA2B22",
- BLAKE2B_3_PUBLIC_0: "6DDE6DDEDE04254B9BC75D04017D4F4406AC7A5F7374550C1EECC8594BFB1E70",
- BLAKE2B_3_ADDRESS_0: "nano_1ugyfqhfw337bgfwgqa617ynyj18ojx7ywuncn83xu8ad77zp9mip188iakf"
-})
-
-export const BIP32_TEST_VECTORS = Object.freeze({
- SEED_0: '000102030405060708090a0b0c0d0e0f',
- m_PUB_0: 'xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8',
- m_PRV_0: 'xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi',
- m_0H_PUB_0: 'xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw',
- m_0H_PRV_0: 'xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7',
- m_0H_1_PUB_0: 'xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ',
- m_0H_1_PRV_0: 'xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs',
- m_0H_1_2H_PUB_0: 'xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5',
- m_0H_1_2H_PRV_0: 'xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM',
- m_0H_1_2H_2_PUB_0: 'xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV',
- m_0H_1_2H_2_PRV_0: 'xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334',
- m_0H_1_2H_2_1000000000_PUB_0: 'xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy',
- m_0H_1_2H_2_1000000000_PRV_0: 'xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76',
-
- SEED_1: 'fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542',
- m_PUB_1: 'xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB',
- m_PRV_1: 'xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U',
- m_0_PUB_1: 'xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH',
- m_0_PRV_1: 'xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt',
- m_0_2147483647H_PUB_1: 'xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a',
- m_0_2147483647H_PRV_1: 'xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9',
- m_0_2147483647H_1_PUB_1: 'xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon',
- m_0_2147483647H_1_PRV_1: 'xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef',
- m_0_2147483647H_1_2147483646H_PUB_1: 'xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL',
- m_0_2147483647H_1_2147483646H_PRV_1: 'xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc',
- m_0_2147483647H_1_2147483646H_2_PUB_1: 'xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt',
- m_0_2147483647H_1_2147483646H_2_PRV_1: 'xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j',
-
- /**
- * These vectors test for the retention of leading zeros.
- * See bitpay / bitcore - lib#47 and iancoleman / bip39#58 for more information.
- */
- SEED_2: '4b381541583be4423346c643850da4b320e46a87ae3d2a4e6da11eba819cd4acba45d239319ac14f863b8d5ab5a0d0c64d2e8a1e7d1457df2e5a3c51c73235be',
- m_PUB_2: 'xpub661MyMwAqRbcEZVB4dScxMAdx6d4nFc9nvyvH3v4gJL378CSRZiYmhRoP7mBy6gSPSCYk6SzXPTf3ND1cZAceL7SfJ1Z3GC8vBgp2epUt13',
- m_PRV_2: 'xprv9s21ZrQH143K25QhxbucbDDuQ4naNntJRi4KUfWT7xo4EKsHt2QJDu7KXp1A3u7Bi1j8ph3EGsZ9Xvz9dGuVrtHHs7pXeTzjuxBrCmmhgC6',
- m_0H_PUB_2: 'xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y',
- m_0H_PRV_2: 'xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L',
-
- /**
- * These vectors test for the retention of leading zeros.
- * See btcsuite / btcutil#172 for more information.
- */
-
- SEED_3: '3ddd5602285899a946114506157c7997e5444528f3003f6134712147db19b678',
- m_PUB_3: 'xpub661MyMwAqRbcGczjuMoRm6dXaLDEhW1u34gKenbeYqAix21mdUKJyuyu5F1rzYGVxyL6tmgBUAEPrEz92mBXjByMRiJdba9wpnN37RLLAXa',
- m_PRV_3: 'xprv9s21ZrQH143K48vGoLGRPxgo2JNkJ3J3fqkirQC2zVdk5Dgd5w14S7fRDyHH4dWNHUgkvsvNDCkvAwcSHNAQwhwgNMgZhLtQC63zxwhQmRv',
- m_0H_PUB_3: 'xpub69AUMk3qDBi3uW1sXgjCmVjJ2G6WQoYSnNHyzkmdCHEhSZ4tBok37xfFEqHd2AddP56Tqp4o56AePAgCjYdvpW2PU2jbUPFKsav5ut6Ch1m',
- m_0H_PRV_3: 'xprv9vB7xEWwNp9kh1wQRfCCQMnZUEG21LpbR9NPCNN1dwhiZkjjeGRnaALmPXCX7SgjFTiCTT6bXes17boXtjq3xLpcDjzEuGLQBM5ohqkao9G',
- m_0H_1H_PUB_3: 'xpub6BJA1jSqiukeaesWfxe6sNK9CCGaujFFSJLomWHprUL9DePQ4JDkM5d88n49sMGJxrhpjazuXYWdMf17C9T5XnxkopaeS7jGk1GyyVziaMt',
- m_0H_1H_PRV_3: 'xprv9xJocDuwtYCMNAo3Zw76WENQeAS6WGXQ55RCy7tDJ8oALr4FWkuVoHJeHVAcAqiZLE7Je3vZJHxspZdFHfnBEjHqU5hG1Jaj32dVoS6XLT1',
-
- /**
- * These vectors test that invalid extended keys are recognized as invalid.
- */
- INVALID_0: 'xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6LBpB85b3D2yc8sfvZU521AAwdZafEz7mnzBBsz4wKY5fTtTQBm', // (pubkey version / prvkey mismatch)
- INVALID_1: 'xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFGTQQD3dC4H2D5GBj7vWvSQaaBv5cxi9gafk7NF3pnBju6dwKvH', // (prvkey version / pubkey mismatch)
- INVALID_2: 'xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6Txnt3siSujt9RCVYsx4qHZGc62TG4McvMGcAUjeuwZdduYEvFn', // (invalid pubkey prefix 04)
- INVALID_3: 'xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFGpWnsj83BHtEy5Zt8CcDr1UiRXuWCmTQLxEK9vbz5gPstX92JQ', // (invalid prvkey prefix 04)
- INVALID_4: 'xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6N8ZMMXctdiCjxTNq964yKkwrkBJJwpzZS4HS2fxvyYUA4q2Xe4', // (invalid pubkey prefix 01)
- INVALID_5: 'xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFAzHGBP2UuGCqWLTAPLcMtD9y5gkZ6Eq3Rjuahrv17fEQ3Qen6J', // (invalid prvkey prefix 01)
- INVALID_6: 'xprv9s2SPatNQ9Vc6GTbVMFPFo7jsaZySyzk7L8n2uqKXJen3KUmvQNTuLh3fhZMBoG3G4ZW1N2kZuHEPY53qmbZzCHshoQnNf4GvELZfqTUrcv', // (zero depth with non - zero parent fingerprint)
- INVALID_7: 'xpub661no6RGEX3uJkY4bNnPcw4URcQTrSibUZ4NqJEw5eBkv7ovTwgiT91XX27VbEXGENhYRCf7hyEbWrR3FewATdCEebj6znwMfQkhRYHRLpJ', // (zero depth with non - zero parent fingerprint)
- INVALID_8: 'xprv9s21ZrQH4r4TsiLvyLXqM9P7k1K3EYhA1kkD6xuquB5i39AU8KF42acDyL3qsDbU9NmZn6MsGSUYZEsuoePmjzsB3eFKSUEh3Gu1N3cqVUN', // (zero depth with non - zero index)
- INVALID_9: 'xpub661MyMwAuDcm6CRQ5N4qiHKrJ39Xe1R1NyfouMKTTWcguwVcfrZJaNvhpebzGerh7gucBvzEQWRugZDuDXjNDRmXzSZe4c7mnTK97pTvGS8', // (zero depth with non - zero index)
- INVALID_10: 'DMwo58pR1QLEFihHiXPVykYB6fJmsTeHvyTp7hRThAtCX8CvYzgPcn8XnmdfHGMQzT7ayAmfo4z3gY5KfbrZWZ6St24UVf2Qgo6oujFktLHdHY4', // (unknown extended key version)
- INVALID_11: 'DMwo58pR1QLEFihHiXPVykYB6fJmsTeHvyTp7hRThAtCX8CvYzgPcn8XnmdfHPmHJiEDXkTiJTVV9rHEBUem2mwVbbNfvT2MTcAqj3nesx8uBf9', // (unknown extended key version)
- INVALID_12: 'xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzF93Y5wvzdUayhgkkFoicQZcP3y52uPPxFnfoLZB21Teqt1VvEHx', // (private key 0 not in 1..n - 1)
- INVALID_13: 'xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFAzHGBP2UuGCqWLTAPLcMtD5SDKr24z3aiUvKr9bJpdrcLg1y3G', // (private key n not in 1..n - 1)
- INVALID_14: 'xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6Q5JXayek4PRsn35jii4veMimro1xefsM58PgBMrvdYre8QyULY', // (invalid pubkey 020000000000000000000000000000000000000000000000000000000000000007)
- INVALID_15: 'xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHL' // (invalid checksum)
-})
-
-export const CUSTOM_TEST_VECTORS = Object.freeze({
- ENTROPY_0: "00000000000000000000000000000000",
- MNEMONIC_0: "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
- SEED_0: "5EB00BBDDCF069084889A8AB9155568165F5C453CCB85E70811AAED6F6DA5FC19A5AC40B389CD370D086206DEC8AA6C43DAEA6690F20AD3D8D48B2D2CE9E38E4",
- PRIVATE_0: "7F72C7D17BEAC5CDC249D3AEBA8BF76D640129F69DB17E584A4A98E635855D7C",
- PUBLIC_0: "588FAABCE802DF8C1700BDF50F2861DE1C0FA48B38B27ECE910D7C696759BAF5",
- ADDRESS_0: "nano_1p6hocygi1pzjidi3hho3wn85qiw3ykapg7khu9b45dwf7momgqoytn1c1jz",
-
- ENTROPY_1: "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f",
- MNEMONIC_1: "legal winner thank year wave sausage worth useful legal winner thank year wave sausage wise",
- SEED_1: "D95F1FAA0F8AEA406101A81510690D781DA04C86678FC5A13A09C251B7505BB6D17EC0BB408F9D2D6BC9434ADBD79491F09F91186B1E445A392D682D8DB586AD",
- PRIVATE_1: "8971838804CE4D715A9250D673EACCAEA7AF26349B6E43B50CCC5554DF0BD342",
- PUBLIC_1: "D1DBB524EF0A1A56C91E2EDCE4D7E1A5814CCC45C1B18EDF657E2859BB96A1E9",
- ADDRESS_1: "nano_3ngupnkgy4itcu6jwdpwwmdy5be3bm86difjjuhpczjad8xsfahbg61c7ipy",
-
- ENTROPY_2: "808080808080808080808080808080808080808080808080",
- MNEMONIC_2: "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always",
- SEED_2: "04D5F77103510C41D610F7F5FB3F0BADC77C377090815CEE808EA5D2F264FDFABF7C7DED4BE6D4C6D7CDB021BA4C777B0B7E57CA8AA6DE15AEB9905DBA674D66",
- PRIVATE_2: "50F76F0211E8F18D3554C6C0DD8131E75BDBB2AC392BF6FBE23698E900EFCA13",
- PUBLIC_2: "9C93BD3C0796381F7562E3E14D2E3CF0F4056226149D7CAC891B241434B4285A",
- ADDRESS_2: "nano_396mqny1h7jr5xtp7rz3bnq5sw9n1oj4e76xhkpak8s64itdac4t95ux7xn4",
-
- ENTROPY_3: "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
- MNEMONIC_3: "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo veteran",
- SEED_3: "DB4BFE5911205C0B2E048CEEF790D0433A902A070D0744AF9B5E88ED5E0AEF548246102DD6BA2313E418FD799360E2DBD8EB93EE40FE0942517555B66E89D488",
- PRIVATE_3: "133F351F1EDF5B4FE86EA7849AEC2C7E4D3F5F16C0CBAB4A236ADF17ACCB98B0",
- PUBLIC_3: "2D6E50265036DE634FC71A2F9BE8A336AB991B8751C15D883ACCD90BFD3BEDB6",
- ADDRESS_3: "nano_1ddgc1m71fpyef9wg8jhmhnc8fodm6frgng3dp65om8s3hymqufp8jefijxu",
-})
--- /dev/null
+// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+/**
+* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+*
+* Do not send any funds to the test vectors below!
+*
+* Sources:
+* https://docs.nano.org/integration-guides/key-management/#test-vectors
+* https://docs.nano.org/integration-guides/key-management/#creating-transactions
+* https://github.com/trezor/python-mnemonic/blob/master/vectors.json
+* https://tools.nanos.cc/?tool=seed
+*/
+export const GENESIS_ADDRESS = 'nano_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3'
+export const RAW_MAX = '340282366920938463463374607431768211455'
+export const SUPPLY_MAX = '133248297920938463463374607431768211455'
+
+export const NANO_TEST_VECTORS = Object.freeze({
+ MNEMONIC: 'edge defense waste choose enrich upon flee junk siren film clown finish luggage leader kid quick brick print evidence swap drill paddle truly occur',
+ PASSWORD: 'some password',
+ BIP39_SEED: '0DC285FDE768F7FF29B66CE7252D56ED92FE003B605907F7A4F683C3DC8586D34A914D3C71FC099BB38EE4A59E5B081A3497B7A323E90CC68F67B5837690310C',
+
+ PRIVATE_0: '3BE4FC2EF3F3B7374E6FC4FB6E7BB153F8A2998B3B3DAB50853EABE128024143',
+ PUBLIC_0: '5B65B0E8173EE0802C2C3E6C9080D1A16B06DE1176C938A924F58670904E82C4',
+ ADDRESS_0: 'nano_1pu7p5n3ghq1i1p4rhmek41f5add1uh34xpb94nkbxe8g4a6x1p69emk8y1d',
+
+ PRIVATE_1: 'CE7E429E683D652446261C17A96DA9ED1897AEA96C8046F2B8036F6B05CB1A83',
+ PUBLIC_1: 'D9F7762E9CD4E7ED632481308CDB8F54ABF0241332C0A8641F61E92E2FB03C12',
+ ADDRESS_1: 'nano_3phqgrqbso99xojkb1bijmfryo7dy1k38ep1o3k3yrhb7rqu1h1k47yu78gz',
+
+ PRIVATE_2: '1257DF74609B9C6461A3F4E7FD6E3278F2DDCF2562694F2C3AA0515AF4F09E38',
+ PUBLIC_2: 'A46DA51986E25A14D82E32D765DCEE69B9EECCD4405411430D91DDB61B717566',
+ ADDRESS_2: 'nano_3b5fnnerfrkt4me4wepqeqggwtfsxu8fai4n473iu6gxprfq4xd8pk9gh1dg',
+
+ SEND_BLOCK: {
+ account: "nano_1e5aqegc1jb7qe964u4adzmcezyo6o146zb8hm6dft8tkp79za3sxwjym5rx",
+ previous: "92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D",
+ representative: "nano_1stofnrxuz3cai7ze75o174bpm7scwj9jn3nxsn8ntzg784jf1gzn1jjdkou",
+ balance: "11618869000000000000000000000000",
+ link: "nano_1q3hqecaw15cjt7thbtxu3pbzr1eihtzzpzxguoc37bj1wc5ffoh7w74gi6p",
+ hash: "BB569136FA05F8CBF65CEF2EDE368475B289C4477342976556BA4C0DDF216E45",
+ key: "781186FB9EF17DB6E3D1056550D9FAE5D5BBADA6A6BC370E4CBB938B1DC71DA3",
+ signature: "74BCC59DBA39A1E34A5F75F96D6DE9154E3477AAD7DE30EA563DFCFE501A804228008F98DDF4A15FD35705102785C50EF76732C3A74B0FEC5B0DD67B574A5900",
+ work: "fbffed7c73b61367"
+ },
+ RECEIVE_BLOCK: {
+ account: "nano_1e5aqegc1jb7qe964u4adzmcezyo6o146zb8hm6dft8tkp79za3sxwjym5rx",
+ previous: "92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D",
+ representative: "nano_1stofnrxuz3cai7ze75o174bpm7scwj9jn3nxsn8ntzg784jf1gzn1jjdkou",
+ balance: "11618869000000000000000000000000",
+ link: "CBC911F57B6827649423C92C88C0C56637A4274FF019E77E24D61D12B5338783",
+ hash: "350D145570578A36D3D5ADE58DC7465F4CAAF257DD55BD93055FF826057E2CDD",
+ key: "781186FB9EF17DB6E3D1056550D9FAE5D5BBADA6A6BC370E4CBB938B1DC71DA3",
+ signature: "EEFFE1EFCCC8F2F6F2F1B79B80ABE855939DD9D6341323186494ADEE775DAADB3B6A6A07A85511F2185F6E739C4A54F1454436E22255A542ED879FD04FEED001",
+ work: "c5cf86de24b24419"
+ },
+ OPEN_BLOCK: {
+ account: "nano_1rawdji18mmcu9psd6h87qath4ta7iqfy8i4rqi89sfdwtbcxn57jm9k3q11",
+ previous: "0000000000000000000000000000000000000000000000000000000000000000",
+ representative: "nano_1stofnrxuz3cai7ze75o174bpm7scwj9jn3nxsn8ntzg784jf1gzn1jjdkou",
+ balance: "100",
+ link: "5B2DA492506339C0459867AA1DA1E7EDAAC4344342FAB0848F43B46D248C8E99",
+ hash: "ED3BE5340CC9D62964B5A5F84375A06078CBEDC45FB5FA2926985D6E27D803BB",
+ key: "0ED82E6990A16E7AD2375AB5D54BEAABF6C676D09BEC74D9295FCAE35439F694",
+ signature: "C4C1D0E25E9E1118F0E139704E9001FF54BDABAB4C3A59DE24510E5B48F269ACBC2F3393DFA46B390CA9C6831074829D91E694B81E8C0C2C9C4FA49A757ECB03",
+ work: "08d09dc3405d9441"
+ }
+})
+
+export const TREZOR_TEST_VECTORS = Object.freeze({
+ PASSWORD: 'TREZOR',
+
+ ENTROPY_0: "0000000000000000000000000000000000000000000000000000000000000000",
+ MNEMONIC_0: "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
+ SEED_0: "bda85446c68413707090a52022edd26a1c9462295029f2e60cd7c4f2bbd3097170af7a4d73245cafa9c3cca8d561a7c3de6f5d4a10be8ed2a5e608d68f92fcc8",
+ BIP32_KEY_0: "xprv9s21ZrQH143K32qBagUJAMU2LsHg3ka7jqMcV98Y7gVeVyNStwYS3U7yVVoDZ4btbRNf4h6ibWpY22iRmXq35qgLs79f312g2kj5539ebPM",
+ BLAKE2B_PRIVATE_0: "9F0E444C69F77A49BD0BE89DB92C38FE713E0963165CCA12FAF5712D7657120F",
+ BLAKE2B_PUBLIC_0: "C008B814A7D269A1FA3C6528B19201A24D797912DB9996FF02A1FF356E45552B",
+ BLAKE2B_ADDRESS_0: "nano_3i1aq1cchnmbn9x5rsbap8b15akfh7wj7pwskuzi7ahz8oq6cobd99d4r3b7",
+
+ ENTROPY_1: "7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F",
+ MNEMONIC_1: "legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title",
+ SEED_1: "bc09fca1804f7e69da93c2f2028eb238c227f2e9dda30cd63699232578480a4021b146ad717fbb7e451ce9eb835f43620bf5c514db0f8add49f5d121449d3e87",
+ BIP32_KEY_1: "xprv9s21ZrQH143K3Y1sd2XVu9wtqxJRvybCfAetjUrMMco6r3v9qZTBeXiBZkS8JxWbcGJZyio8TrZtm6pkbzG8SYt1sxwNLh3Wx7to5pgiVFU",
+ BLAKE2B_1_PRIVATE_0: "C54F9F69B088B554FF494D4CE7D23EB1B13E89D338F219F83BC91F415C3F7F2D",
+ BLAKE2B_1_PUBLIC_0: "1573BD1B96ECF80571BF544854026E6A967F065028FBC514B548471DC60B3229",
+ BLAKE2B_1_ADDRESS_0: "nano_17dmqnfsfu9r1oruyo4aci38wtnphw571c9urncdck495q51pejbp3c648yo",
+ BLAKE2B_1_PRIVATE_1: "1B704560A0A04EAFD81E8D13481370DA458E2BB00C57F3AA00120D80F6A2BB6F",
+ BLAKE2B_1_PUBLIC_1: "353288BD57F98A2FC940B4D5A5CE9194EF1598611B00C629E96189320AC7409F",
+ BLAKE2B_1_ADDRESS_1: "nano_1fbkj4yohyec7z6n3f8onq9b579h4pe848r1rrnykreb8a7egi6z14nozo43",
+
+ ENTROPY_2: "8080808080808080808080808080808080808080808080808080808080808080",
+ MNEMONIC_2: "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless",
+ SEED_2: "c0c519bd0e91a2ed54357d9d1ebef6f5af218a153624cf4f2da911a0ed8f7a09e2ef61af0aca007096df430022f7a2b6fb91661a9589097069720d015e4e982f",
+ BIP32_KEY_2: "xprv9s21ZrQH143K3CSnQNYC3MqAAqHwxeTLhDbhF43A4ss4ciWNmCY9zQGvAKUSqVUf2vPHBTSE1rB2pg4avopqSiLVzXEU8KziNnVPauTqLRo",
+ BLAKE2B_2_PRIVATE_0: "554BE953D1E2DAAD0F8CBC2002967FC158E57032A6C4FD107FFEB2ACA518B613",
+ BLAKE2B_2_PUBLIC_0: "D85DECD78A303A18CC0D7B65FB384B9C49A7E2EF3666250CBD4F6EC4791513F8",
+ BLAKE2B_2_ADDRESS_0: "nano_3p4xxmdrne3t5581tyu7zew6q94bnzjgyfm86n8dtmugrjwjc6zrrci4g1rc",
+
+ ENTROPY_3: "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+ MNEMONIC_3: "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote",
+ SEED_3: "dd48c104698c30cfe2b6142103248622fb7bb0ff692eebb00089b32d22484e1613912f0a5b694407be899ffd31ed3992c456cdf60f5d4564b8ba3f05a69890ad",
+ BIP32_KEY_3: "xprv9s21ZrQH143K2WFF16X85T2QCpndrGwx6GueB72Zf3AHwHJaknRXNF37ZmDrtHrrLSHvbuRejXcnYxoZKvRquTPyp2JiNG3XcjQyzSEgqCB",
+ BLAKE2B_3_PRIVATE_0: "F1FD8CBD15A54FABDED17C65C4DD44E1F93AAD122FCC1840B1EDEFAAA5BA2B22",
+ BLAKE2B_3_PUBLIC_0: "6DDE6DDEDE04254B9BC75D04017D4F4406AC7A5F7374550C1EECC8594BFB1E70",
+ BLAKE2B_3_ADDRESS_0: "nano_1ugyfqhfw337bgfwgqa617ynyj18ojx7ywuncn83xu8ad77zp9mip188iakf"
+})
+
+export const BIP32_TEST_VECTORS = Object.freeze({
+ SEED_0: '000102030405060708090a0b0c0d0e0f',
+ m_PUB_0: 'xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8',
+ m_PRV_0: 'xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi',
+ m_0H_PUB_0: 'xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw',
+ m_0H_PRV_0: 'xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7',
+ m_0H_1_PUB_0: 'xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ',
+ m_0H_1_PRV_0: 'xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs',
+ m_0H_1_2H_PUB_0: 'xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5',
+ m_0H_1_2H_PRV_0: 'xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM',
+ m_0H_1_2H_2_PUB_0: 'xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV',
+ m_0H_1_2H_2_PRV_0: 'xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334',
+ m_0H_1_2H_2_1000000000_PUB_0: 'xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy',
+ m_0H_1_2H_2_1000000000_PRV_0: 'xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76',
+
+ SEED_1: 'fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542',
+ m_PUB_1: 'xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB',
+ m_PRV_1: 'xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U',
+ m_0_PUB_1: 'xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH',
+ m_0_PRV_1: 'xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt',
+ m_0_2147483647H_PUB_1: 'xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a',
+ m_0_2147483647H_PRV_1: 'xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9',
+ m_0_2147483647H_1_PUB_1: 'xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon',
+ m_0_2147483647H_1_PRV_1: 'xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef',
+ m_0_2147483647H_1_2147483646H_PUB_1: 'xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL',
+ m_0_2147483647H_1_2147483646H_PRV_1: 'xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc',
+ m_0_2147483647H_1_2147483646H_2_PUB_1: 'xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt',
+ m_0_2147483647H_1_2147483646H_2_PRV_1: 'xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j',
+
+ /**
+ * These vectors test for the retention of leading zeros.
+ * See bitpay / bitcore - lib#47 and iancoleman / bip39#58 for more information.
+ */
+ SEED_2: '4b381541583be4423346c643850da4b320e46a87ae3d2a4e6da11eba819cd4acba45d239319ac14f863b8d5ab5a0d0c64d2e8a1e7d1457df2e5a3c51c73235be',
+ m_PUB_2: 'xpub661MyMwAqRbcEZVB4dScxMAdx6d4nFc9nvyvH3v4gJL378CSRZiYmhRoP7mBy6gSPSCYk6SzXPTf3ND1cZAceL7SfJ1Z3GC8vBgp2epUt13',
+ m_PRV_2: 'xprv9s21ZrQH143K25QhxbucbDDuQ4naNntJRi4KUfWT7xo4EKsHt2QJDu7KXp1A3u7Bi1j8ph3EGsZ9Xvz9dGuVrtHHs7pXeTzjuxBrCmmhgC6',
+ m_0H_PUB_2: 'xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y',
+ m_0H_PRV_2: 'xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L',
+
+ /**
+ * These vectors test for the retention of leading zeros.
+ * See btcsuite / btcutil#172 for more information.
+ */
+ SEED_3: '3ddd5602285899a946114506157c7997e5444528f3003f6134712147db19b678',
+ m_PUB_3: 'xpub661MyMwAqRbcGczjuMoRm6dXaLDEhW1u34gKenbeYqAix21mdUKJyuyu5F1rzYGVxyL6tmgBUAEPrEz92mBXjByMRiJdba9wpnN37RLLAXa',
+ m_PRV_3: 'xprv9s21ZrQH143K48vGoLGRPxgo2JNkJ3J3fqkirQC2zVdk5Dgd5w14S7fRDyHH4dWNHUgkvsvNDCkvAwcSHNAQwhwgNMgZhLtQC63zxwhQmRv',
+ m_0H_PUB_3: 'xpub69AUMk3qDBi3uW1sXgjCmVjJ2G6WQoYSnNHyzkmdCHEhSZ4tBok37xfFEqHd2AddP56Tqp4o56AePAgCjYdvpW2PU2jbUPFKsav5ut6Ch1m',
+ m_0H_PRV_3: 'xprv9vB7xEWwNp9kh1wQRfCCQMnZUEG21LpbR9NPCNN1dwhiZkjjeGRnaALmPXCX7SgjFTiCTT6bXes17boXtjq3xLpcDjzEuGLQBM5ohqkao9G',
+ m_0H_1H_PUB_3: 'xpub6BJA1jSqiukeaesWfxe6sNK9CCGaujFFSJLomWHprUL9DePQ4JDkM5d88n49sMGJxrhpjazuXYWdMf17C9T5XnxkopaeS7jGk1GyyVziaMt',
+ m_0H_1H_PRV_3: 'xprv9xJocDuwtYCMNAo3Zw76WENQeAS6WGXQ55RCy7tDJ8oALr4FWkuVoHJeHVAcAqiZLE7Je3vZJHxspZdFHfnBEjHqU5hG1Jaj32dVoS6XLT1',
+
+ /**
+ * These vectors test that invalid extended keys are recognized as invalid.
+ */
+ INVALID_0: 'xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6LBpB85b3D2yc8sfvZU521AAwdZafEz7mnzBBsz4wKY5fTtTQBm', // (pubkey version / prvkey mismatch)
+ INVALID_1: 'xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFGTQQD3dC4H2D5GBj7vWvSQaaBv5cxi9gafk7NF3pnBju6dwKvH', // (prvkey version / pubkey mismatch)
+ INVALID_2: 'xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6Txnt3siSujt9RCVYsx4qHZGc62TG4McvMGcAUjeuwZdduYEvFn', // (invalid pubkey prefix 04)
+ INVALID_3: 'xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFGpWnsj83BHtEy5Zt8CcDr1UiRXuWCmTQLxEK9vbz5gPstX92JQ', // (invalid prvkey prefix 04)
+ INVALID_4: 'xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6N8ZMMXctdiCjxTNq964yKkwrkBJJwpzZS4HS2fxvyYUA4q2Xe4', // (invalid pubkey prefix 01)
+ INVALID_5: 'xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFAzHGBP2UuGCqWLTAPLcMtD9y5gkZ6Eq3Rjuahrv17fEQ3Qen6J', // (invalid prvkey prefix 01)
+ INVALID_6: 'xprv9s2SPatNQ9Vc6GTbVMFPFo7jsaZySyzk7L8n2uqKXJen3KUmvQNTuLh3fhZMBoG3G4ZW1N2kZuHEPY53qmbZzCHshoQnNf4GvELZfqTUrcv', // (zero depth with non - zero parent fingerprint)
+ INVALID_7: 'xpub661no6RGEX3uJkY4bNnPcw4URcQTrSibUZ4NqJEw5eBkv7ovTwgiT91XX27VbEXGENhYRCf7hyEbWrR3FewATdCEebj6znwMfQkhRYHRLpJ', // (zero depth with non - zero parent fingerprint)
+ INVALID_8: 'xprv9s21ZrQH4r4TsiLvyLXqM9P7k1K3EYhA1kkD6xuquB5i39AU8KF42acDyL3qsDbU9NmZn6MsGSUYZEsuoePmjzsB3eFKSUEh3Gu1N3cqVUN', // (zero depth with non - zero index)
+ INVALID_9: 'xpub661MyMwAuDcm6CRQ5N4qiHKrJ39Xe1R1NyfouMKTTWcguwVcfrZJaNvhpebzGerh7gucBvzEQWRugZDuDXjNDRmXzSZe4c7mnTK97pTvGS8', // (zero depth with non - zero index)
+ INVALID_10: 'DMwo58pR1QLEFihHiXPVykYB6fJmsTeHvyTp7hRThAtCX8CvYzgPcn8XnmdfHGMQzT7ayAmfo4z3gY5KfbrZWZ6St24UVf2Qgo6oujFktLHdHY4', // (unknown extended key version)
+ INVALID_11: 'DMwo58pR1QLEFihHiXPVykYB6fJmsTeHvyTp7hRThAtCX8CvYzgPcn8XnmdfHPmHJiEDXkTiJTVV9rHEBUem2mwVbbNfvT2MTcAqj3nesx8uBf9', // (unknown extended key version)
+ INVALID_12: 'xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzF93Y5wvzdUayhgkkFoicQZcP3y52uPPxFnfoLZB21Teqt1VvEHx', // (private key 0 not in 1..n - 1)
+ INVALID_13: 'xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFAzHGBP2UuGCqWLTAPLcMtD5SDKr24z3aiUvKr9bJpdrcLg1y3G', // (private key n not in 1..n - 1)
+ INVALID_14: 'xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6Q5JXayek4PRsn35jii4veMimro1xefsM58PgBMrvdYre8QyULY', // (invalid pubkey 020000000000000000000000000000000000000000000000000000000000000007)
+ INVALID_15: 'xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHL' // (invalid checksum)
+})
+
+export const CUSTOM_TEST_VECTORS = Object.freeze({
+ ENTROPY_0: "00000000000000000000000000000000",
+ MNEMONIC_0: "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
+ SEED_0: "5EB00BBDDCF069084889A8AB9155568165F5C453CCB85E70811AAED6F6DA5FC19A5AC40B389CD370D086206DEC8AA6C43DAEA6690F20AD3D8D48B2D2CE9E38E4",
+ PRIVATE_0: "7F72C7D17BEAC5CDC249D3AEBA8BF76D640129F69DB17E584A4A98E635855D7C",
+ PUBLIC_0: "588FAABCE802DF8C1700BDF50F2861DE1C0FA48B38B27ECE910D7C696759BAF5",
+ ADDRESS_0: "nano_1p6hocygi1pzjidi3hho3wn85qiw3ykapg7khu9b45dwf7momgqoytn1c1jz",
+
+ ENTROPY_1: "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f",
+ MNEMONIC_1: "legal winner thank year wave sausage worth useful legal winner thank year wave sausage wise",
+ SEED_1: "D95F1FAA0F8AEA406101A81510690D781DA04C86678FC5A13A09C251B7505BB6D17EC0BB408F9D2D6BC9434ADBD79491F09F91186B1E445A392D682D8DB586AD",
+ PRIVATE_1: "8971838804CE4D715A9250D673EACCAEA7AF26349B6E43B50CCC5554DF0BD342",
+ PUBLIC_1: "D1DBB524EF0A1A56C91E2EDCE4D7E1A5814CCC45C1B18EDF657E2859BB96A1E9",
+ ADDRESS_1: "nano_3ngupnkgy4itcu6jwdpwwmdy5be3bm86difjjuhpczjad8xsfahbg61c7ipy",
+
+ ENTROPY_2: "808080808080808080808080808080808080808080808080",
+ MNEMONIC_2: "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always",
+ SEED_2: "04D5F77103510C41D610F7F5FB3F0BADC77C377090815CEE808EA5D2F264FDFABF7C7DED4BE6D4C6D7CDB021BA4C777B0B7E57CA8AA6DE15AEB9905DBA674D66",
+ PRIVATE_2: "50F76F0211E8F18D3554C6C0DD8131E75BDBB2AC392BF6FBE23698E900EFCA13",
+ PUBLIC_2: "9C93BD3C0796381F7562E3E14D2E3CF0F4056226149D7CAC891B241434B4285A",
+ ADDRESS_2: "nano_396mqny1h7jr5xtp7rz3bnq5sw9n1oj4e76xhkpak8s64itdac4t95ux7xn4",
+
+ ENTROPY_3: "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ MNEMONIC_3: "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo veteran",
+ SEED_3: "DB4BFE5911205C0B2E048CEEF790D0433A902A070D0744AF9B5E88ED5E0AEF548246102DD6BA2313E418FD799360E2DBD8EB93EE40FE0942517555B66E89D488",
+ PRIVATE_3: "133F351F1EDF5B4FE86EA7849AEC2C7E4D3F5F16C0CBAB4A236ADF17ACCB98B0",
+ PUBLIC_3: "2D6E50265036DE634FC71A2F9BE8A336AB991B8751C15D883ACCD90BFD3BEDB6",
+ ADDRESS_3: "nano_1ddgc1m71fpyef9wg8jhmhnc8fodm6frgng3dp65om8s3hymqufp8jefijxu",
+})
+
+export const BLAKE2B_TEST_VECTORS = Object.freeze({
+ LIBSODIUM: [
+ { "outlen": 1, "out": "ba", "in": "", "key": "00", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 2, "out": "6139", "in": "00", "key": "0001", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 3, "out": "3a1666", "in": "0001", "key": "000102", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 4, "out": "5797e9d0", "in": "000102", "key": "00010203", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 5, "out": "834a26efe6", "in": "00010203", "key": "0001020304", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 6, "out": "d7e9e862bbce", "in": "0001020304", "key": "000102030405", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 7, "out": "40d8b84c374750", "in": "000102030405", "key": "00010203040506", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 8, "out": "276789189244cf04", "in": "00010203040506", "key": "0001020304050607", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 9, "out": "16f73ffe0673cc9992", "in": "0001020304050607", "key": "000102030405060708", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 10, "out": "b3835bfaf6eb71d94078", "in": "000102030405060708", "key": "00010203040506070809", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 11, "out": "8c624e844d34f4a59f34cc", "in": "00010203040506070809", "key": "000102030405060708090a", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 12, "out": "e0a394962413ad09975df3cf", "in": "000102030405060708090a", "key": "000102030405060708090a0b", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 13, "out": "47f043c3aacb501f97e0458ae3", "in": "000102030405060708090a0b", "key": "000102030405060708090a0b0c", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 14, "out": "b4a11f2fb72a7e6f96fdacf98d49", "in": "000102030405060708090a0b0c", "key": "000102030405060708090a0b0c0d", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 15, "out": "f434079e9adeb244047cb6855f9854", "in": "000102030405060708090a0b0c0d", "key": "000102030405060708090a0b0c0d0e", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 16, "out": "5fbe885c4b2d4e0d78dc5905622a277a", "in": "000102030405060708090a0b0c0d0e", "key": "000102030405060708090a0b0c0d0e0f", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 17, "out": "e262ba3e2ab76efdf83513108e3b987d1b", "in": "000102030405060708090a0b0c0d0e0f", "key": "000102030405060708090a0b0c0d0e0f10", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 18, "out": "add93dde78d32e77bc039c34a49043f19d26", "in": "000102030405060708090a0b0c0d0e0f10", "key": "000102030405060708090a0b0c0d0e0f1011", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 19, "out": "093842ac10e2eb1237ddc9ca9e7990cf397772", "in": "000102030405060708090a0b0c0d0e0f1011", "key": "000102030405060708090a0b0c0d0e0f101112", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 20, "out": "09e7f6a0e2ea4888f1dbf6562effd1561c65029c", "in": "000102030405060708090a0b0c0d0e0f101112", "key": "000102030405060708090a0b0c0d0e0f10111213", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 21, "out": "bd33a9ec914f5b81864a49184338e4062d6c6b2b2e", "in": "000102030405060708090a0b0c0d0e0f10111213", "key": "000102030405060708090a0b0c0d0e0f1011121314", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 22, "out": "8dc46295235d94f5881d429a5ad47f9db9e35cf8c6b3", "in": "000102030405060708090a0b0c0d0e0f1011121314", "key": "000102030405060708090a0b0c0d0e0f101112131415", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 23, "out": "ba5df554dca7ac1cba4889fa88adf3070fbf4ab5d187b5", "in": "000102030405060708090a0b0c0d0e0f101112131415", "key": "000102030405060708090a0b0c0d0e0f10111213141516", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 24, "out": "1ff84715e71c66214d271d421395fb6166db97b1d47ed697", "in": "000102030405060708090a0b0c0d0e0f10111213141516", "key": "000102030405060708090a0b0c0d0e0f1011121314151617", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 25, "out": "75a0d227c70549f5b0c933b7b21f151355bd47e04b6085c91f", "in": "000102030405060708090a0b0c0d0e0f1011121314151617", "key": "000102030405060708090a0b0c0d0e0f101112131415161718", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 26, "out": "a32a5c9439a0fa771dcbe7f338b5dcef62a754edc4952614d6f0", "in": "000102030405060708090a0b0c0d0e0f101112131415161718", "key": "000102030405060708090a0b0c0d0e0f10111213141516171819", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 27, "out": "53a87de519cdcc7f64730d58bce6baaf7b44c5c428a4611a208ad4", "in": "000102030405060708090a0b0c0d0e0f10111213141516171819", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 28, "out": "5e5ad8f0c4f083f9b7a5154d9c0dfd0f3d2fce94cf54fc215450314a", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 29, "out": "9c76b9e63c77e6564b1e5111c2fb140046e1e5a4f900a7cfc2bac3fcfa", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 30, "out": "bb919251ca310eb9b994e5d7883bc9fa2144b59b8d5d940677b7130ac777", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 31, "out": "faa492a66f08ef0c7adb868fcb7b523aedd35b8ff1414bd1d554794f144474", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 32, "out": "9b273ebe335540b87be899abe169389ed61ed262c3a0a16e4998bbf752f0bee3", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 33, "out": "1e0070b92429c151b33bdd1bb4430a0e650a3dfc94d404054e93c8568330ecc505", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 34, "out": "e3b64149f1b76231686d592d1d4af984ce2826ba03c2224a92f95f9526130ce4eb40", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 35, "out": "5f8e378120b73db9eefa65ddcdcdcb4acd8046c31a5e47f298caa400937d5623f1394b", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 36, "out": "74c757a4165a1782c933e587353a9fd8f6d7bf26b7f51b52c542747030bfb3d560c2e5c2", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 37, "out": "2d5ee85cc238b923806dd98db18919d1924f2340ec88917d4ce1799cbfd5f2cb9df99db2e1", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 38, "out": "c93ff727e6f9822efec0a77eed0025c0eff19127bf8746b7c71c2a098f57cef02febb86a1e6c", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 39, "out": "adfb6d7ba13779a5dd1bbf268e400f4156f0f5c9d5b670ff539e1d9c1a63373416f3001f338407", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223242526", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 40, "out": "3a6900e58a448887d77c5911e4bdde620e64f25b2d71723fa60f7cb3efa7c320b6153bdbc3287949", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223242526", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324252627", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 41, "out": "413eb0fd379b32dd88e82242a87cc58ce3e64c72352387a4c70f92ee5c8d23fa7ecd86f6df170a32d2", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324252627", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 42, "out": "92d0d3cacc3e25628caf6f2c4cd50d25d154ac45098f531d690230b859f37cfe089eb169f76bba72a3ff", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223242526272829", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 43, "out": "92f6ccc11a9a3bee520b17e0cddc4550c0e9cf47ddd9a6161284259ffb161c1d0675b505cb1066872768e8", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223242526272829", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 44, "out": "a3cd675804e6be7f120138a9eaadcd56bb7763d1c046e87fe0d358c8276b0d24621f46c60b46e397933b75b4", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 45, "out": "304a1af53cbdd6486b8419d1ebd5e9528c540d8dc46a10be49067f46a0617229577015d776783f702b2954df43", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 46, "out": "d8a6358970446453ac0c82c758644ab68989b5b4f06f9768807ce0c5f2a0dbac1e8450f4e3a02deecf7b54b6a45d", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 47, "out": "1264b8dee9ac4aa8de69a43ada95cc95f20230f33836d4a1db8c2466ab38361686e5ac282025ccc2e0f6a1cd98a4dd", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 48, "out": "7eed787abaa7f4e8b8aa3090f0676201cfbaaf350899661cdd5216ac0b5cd874443f5c0688ffd7ca1ccbfe1ca7e1a3f5", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 49, "out": "8907f0218585167962a8e8213559a643dd03c2bf1a7a5ad3e3bc5f88c0ff1532ee8cd29880e7e0e68da22a5798aef27cc5", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 50, "out": "12dea17b0733e5060751b1115e10c3d4b2f4583bcd009d9f1f42ec23d4a6a0df1185d3abbdbe86de08569e70583d6de1c1fe", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 51, "out": "8ff75e91f1de547dc3a25472db2f51f5910a290c449603da54207b5e39bd735d240ec913b52df90709b5d29357971d6c341452", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 52, "out": "4a3b16b12400f38e74778efc3a4caa52ec6fdf6b0180a5bfac9189e52e162c10e8911a54ab33e2b389ee1949e58edaa119e2b2b9", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 53, "out": "c9943e7186fdc9bbfa1d7087fa7086babe6fcf95a6196d1772187854071304e2f1fff39e6e6f48f76addb16d5c00249e0523aac91f", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 54, "out": "0297f16fdd34add9cc87b4adf816525b590ba08ac733c43f8d225d194df4f9c83b4dce617be51e25b5f6c80dff249f27c707de20e422", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 55, "out": "576bb891eab9930998e2e73b5d0498e3c5f040f8dec9397a8c7a622c17de01fee7cc936e3bd4de1f7fd8b31dea9e70c65462bbb5dc7b50", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233343536", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 56, "out": "9416a57ae7c8c51c6e008f940fe06d8ebc02c350c19a2f71583a6d260b085670d73a95248fef0f4cae5292ba7db1189a7cd9c51122ba7913", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233343536", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 57, "out": "ea644b9051cca5eee8868a553e3f0f4e14739e1555474151156e10578256b288a233870dd43a380765400ea446df7f452c1e03a9e5b6731256", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 58, "out": "f99cc1603de221abc1ecb1a7eb4bbf06e99561d1cc5541d8d601bae2b1dd3cbe448ac276667f26de5e269183a09f7deaf35d33174b3cc8ad4aa2", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233343536373839", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 59, "out": "ee2be1ec57fdac23f89402a534177eca0f4b982a4ed2c2e900b6a79e1f47a2d023eff2e647baf4f4c0da3a28d08a44bc780516974074e2523e6651", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233343536373839", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 60, "out": "9cda001868949a2bad96c5b3950a8315e6e5214d0b54dcd596280565d351806ef22cf3053f63623da72fcad9afa3896641658632334c9ec4f644c984", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 61, "out": "c6d6722a916651a8671383d8260873347d9c248696b4cb3dac4dea9ba57ed971127cb18e44211d7e14177ace248b3c6e0785356ee261ebdc6ef0faf143", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 62, "out": "5dd258a3e7505bc6b9776b0df25676a1c19e2c8258c7b5f2e361423523d96299eb6827bc7c27e7bca2d2b59d717c2ebcb05e6dcaa32289d96fae9a4077ef", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 63, "out": "19c14de35fe19c92cc0e624280e4136355d4cfa9a0a98b090c4b06f5665021920725852ff1f566b0c8c37157b25fb9f947a2e70b40577a17860a0732c170ac", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" },
+ { "outlen": 64, "out": "5fcdcc02be7714a0dbc77df498bf999ea9225d564adca1c121c9af03af92cac8177b9b4a86bcc47c79aa32aac58a3fef967b2132e9352d4613fe890beed2571b", "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e", "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", "salt": "35623662343165643962333433666530", "personal": "35313236666232613337343030643261" }
+ ],
+ REFERENCE: [
+ {
+ "in": "",
+ "key": "",
+ "out": "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce"
+ },
+ {
+ "in": "00",
+ "key": "",
+ "out": "2fa3f686df876995167e7c2e5d74c4c7b6e48f8068fe0e44208344d480f7904c36963e44115fe3eb2a3ac8694c28bcb4f5a0f3276f2e79487d8219057a506e4b"
+ },
+ {
+ "in": "0001",
+ "key": "",
+ "out": "1c08798dc641aba9dee435e22519a4729a09b2bfe0ff00ef2dcd8ed6f8a07d15eaf4aee52bbf18ab5608a6190f70b90486c8a7d4873710b1115d3debbb4327b5"
+ },
+ {
+ "in": "000102",
+ "key": "",
+ "out": "40a374727302d9a4769c17b5f409ff32f58aa24ff122d7603e4fda1509e919d4107a52c57570a6d94e50967aea573b11f86f473f537565c66f7039830a85d186"
+ },
+ {
+ "in": "00010203",
+ "key": "",
+ "out": "77ddf4b14425eb3d053c1e84e3469d92c4cd910ed20f92035e0c99d8a7a86cecaf69f9663c20a7aa230bc82f60d22fb4a00b09d3eb8fc65ef547fe63c8d3ddce"
+ },
+ {
+ "in": "0001020304",
+ "key": "",
+ "out": "cbaa0ba7d482b1f301109ae41051991a3289bc1198005af226c5e4f103b66579f461361044c8ba3439ff12c515fb29c52161b7eb9c2837b76a5dc33f7cb2e2e8"
+ },
+ {
+ "in": "000102030405",
+ "key": "",
+ "out": "f95d45cf69af5c2023bdb505821e62e85d7caedf7beda12c0248775b0c88205eeb35af3a90816f6608ce7dd44ec28db1140614e1ddebf3aa9cd1843e0fad2c36"
+ },
+ {
+ "in": "00010203040506",
+ "key": "",
+ "out": "8f945ba700f2530e5c2a7df7d5dce0f83f9efc78c073fe71ae1f88204a4fd1cf70a073f5d1f942ed623aa16e90a871246c90c45b621b3401a5ddbd9df6264165"
+ },
+ {
+ "in": "0001020304050607",
+ "key": "",
+ "out": "e998e0dc03ec30eb99bb6bfaaf6618acc620320d7220b3af2b23d112d8e9cb1262f3c0d60d183b1ee7f096d12dae42c958418600214d04f5ed6f5e718be35566"
+ },
+ {
+ "in": "000102030405060708",
+ "key": "",
+ "out": "6a9a090c61b3410aede7ec9138146ceb2c69662f460c3da53c6515c1eb31f41ca3d280e567882f95cf664a94147d78f42cfc714a40d22ef19470e053493508a2"
+ },
+ {
+ "in": "00010203040506070809",
+ "key": "",
+ "out": "29102511d749db3cc9b4e335fa1f5e8faca8421d558f6a3f3321d50d044a248ba595cfc3efd3d2adc97334da732413f5cbf4751c362ba1d53862ac1e8dabeee8"
+ },
+ {
+ "in": "000102030405060708090a",
+ "key": "",
+ "out": "c97a4779d47e6f77729b5917d0138abb35980ab641bd73a8859eb1ac98c05362ed7d608f2e9587d6ba9e271d343125d40d933a8ed04ec1fe75ec407c7a53c34e"
+ },
+ {
+ "in": "000102030405060708090a0b",
+ "key": "",
+ "out": "10f0dc91b9f845fb95fad6860e6ce1adfa002c7fc327116d44d047cd7d5870d772bb12b5fac00e02b08ac2a0174d0446c36ab35f14ca31894cd61c78c849b48a"
+ },
+ {
+ "in": "000102030405060708090a0b0c",
+ "key": "",
+ "out": "dea9101cac62b8f6a3c650f90eea5bfae2653a4eafd63a6d1f0f132db9e4f2b1b662432ec85b17bcac41e775637881f6aab38dd66dcbd080f0990a7a6e9854fe"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d",
+ "key": "",
+ "out": "441ffaa08cd79dff4afc9b9e5b5620eec086730c25f661b1d6fbfbd1cec3148dd72258c65641f2fca5eb155fadbcabb13c6e21dc11faf72c2a281b7d56145f19"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e",
+ "key": "",
+ "out": "444b240fe3ed86d0e2ef4ce7d851edde22155582aa0914797b726cd058b6f45932e0e129516876527b1dd88fc66d7119f4ab3bed93a61a0e2d2d2aeac336d958"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f",
+ "key": "",
+ "out": "bfbabbef45554ccfa0dc83752a19cc35d5920956b301d558d772282bc867009168e9e98606bb5ba73a385de5749228c925a85019b71f72fe29b3cd37ca52efe6"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f10",
+ "key": "",
+ "out": "9c4d0c3e1cdbbf485bec86f41cec7c98373f0e09f392849aaa229ebfbf397b22085529cb7ef39f9c7c2222a514182b1effaa178cc3687b1b2b6cbcb6fdeb96f8"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f1011",
+ "key": "",
+ "out": "477176b3bfcbadd7657c23c24625e4d0d674d1868f006006398af97aa41877c8e70d3d14c3bbc9bbcdcea801bd0e1599af1f3eec67405170f4e26c964a57a8b7"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112",
+ "key": "",
+ "out": "a78c490eda3173bb3f10dee52f110fb1c08e0302230b85ddd7c11257d92de148785ef00c039c0bb8eb9808a35b2d8c080f572859714c9d4069c5bcaf090e898e"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f10111213",
+ "key": "",
+ "out": "58d023397beb5b4145cb2255b07d74290b36d9fd1e594afbd8eea47c205b2efbfe6f46190faf95af504ab072e36f6c85d767a321bfd7f22687a4abbf494a689c"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f1011121314",
+ "key": "",
+ "out": "4001ec74d5a46fd29c2c3cdbe5d1b9f20e51a941be98d2a4e1e2fbf866a672121db6f81a514cfd10e7358d571bdba48e4ce708b9d124894bc0b5ed554935f73a"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415",
+ "key": "",
+ "out": "ccd1b22dab6511225d2401ea2d8625d206a12473cc732b615e5640cefff0a4adf971b0e827a619e0a80f5db9ccd0962329010d07e34a2064e731c520817b2183"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f10111213141516",
+ "key": "",
+ "out": "b4a0a9e3574edb9e1e72aa31e39cc5f30dbf943f8cabc408449654a39131e66d718a18819143e3ea96b4a1895988a1c0056cf2b6e04f9ac19d657383c2910c44"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f1011121314151617",
+ "key": "",
+ "out": "447becab16630608d39f4f058b16f7af95b85a76aa0fa7cea2b80755fb76e9c804f2ca78f02643c915fbf2fce5e19de86000de03b18861815a83126071f8a37b"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718",
+ "key": "",
+ "out": "54e6dab9977380a5665822db93374eda528d9beb626f9b94027071cb26675e112b4a7fec941ee60a81e4d2ea3ff7bc52cfc45dfbfe735a1c646b2cf6d6a49b62"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f10111213141516171819",
+ "key": "",
+ "out": "3ea62625949e3646704d7e3c906f82f6c028f540f5f72a794b0c57bf97b7649bfeb90b01d3ca3e829de21b3826e6f87014d3c77350cb5a15ff5d468a81bec160"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a",
+ "key": "",
+ "out": "213cfe145c54a33691569980e5938c8883a46d84d149c8ff1a67cd287b4d49c6da69d3a035443db085983d0efe63706bd5b6f15a7da459e8d50a19093db55e80"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b",
+ "key": "",
+ "out": "5716c4a38f38db104e494a0a27cbe89a26a6bb6f499ec01c8c01aa7cb88497e75148cd6eee12a7168b6f78ab74e4be749251a1a74c38c86d6129177e2889e0b6"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c",
+ "key": "",
+ "out": "030460a98bdf9ff17cd96404f28fc304f2b7c04eaade53677fd28f788ca22186b8bc80dd21d17f8549c711aff0e514e19d4e15f5990252a03e082f28dc2052f6"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d",
+ "key": "",
+ "out": "19e7f1ccee88a10672333e390cf22013a8c734c6cb9eab41f17c3c8032a2e4aca0569ea36f0860c7a1af28fa476840d66011168859334a9e4ef9cc2e61a0e29e"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e",
+ "key": "",
+ "out": "29f8b8c78c80f2fcb4bdf7825ed90a70d625ff785d262677e250c04f3720c888d03f8045e4edf3f5285bd39d928a10a7d0a5df00b8484ac2868142a1e8bea351"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "key": "",
+ "out": "5c52920a7263e39d57920ca0cb752ac6d79a04fef8a7a216a1ecb7115ce06d89fd7d735bd6f4272555dba22c2d1c96e6352322c62c5630fde0f4777a76c3de2c"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
+ "key": "",
+ "out": "83b098f262251bf660064a9d3511ce7687a09e6dfbb878299c30e93dfb43a9314db9a600337db26ebeedaf2256a96dabe9b29e7573ad11c3523d874dde5be7ed"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021",
+ "key": "",
+ "out": "9447d98aa5c9331352f43d3e56d0a9a9f9581865998e2885cc56dd0a0bd5a7b50595bd10f7529bcd31f37dc16a1465d594079667da2a3fcb70401498837cedeb"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122",
+ "key": "",
+ "out": "867732f2feeb23893097561ac710a4bff453be9cfbedba8ba324f9d312a82d732e1b83b829fdcd177b882ca0c1bf544b223be529924a246a63cf059bfdc50a1b"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223",
+ "key": "",
+ "out": "f15ab26d4cdfcf56e196bb6ba170a8fccc414de9285afd98a3d3cf2fb88fcbc0f19832ac433a5b2cc2392a4ce34332987d8d2c2bef6c3466138db0c6e42fa47b"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324",
+ "key": "",
+ "out": "2813516d68ed4a08b39d648aa6aacd81e9d655ecd5f0c13556c60fdf0d333ea38464b36c02baccd746e9575e96c63014f074ae34a0a25b320f0fbedd6acf7665"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425",
+ "key": "",
+ "out": "d3259afca8a48962fa892e145acf547f26923ae8d4924c8a531581526b04b44c7af83c643ef5a0bc282d36f3fb04c84e28b351f40c74b69dc7840bc717b6f15f"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223242526",
+ "key": "",
+ "out": "f14b061ae359fa31b989e30332bfe8de8cc8cdb568e14be214a2223b84caab7419549ecfcc96ce2acec119485d87d157d3a8734fc426597d64f36570ceaf224d"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324252627",
+ "key": "",
+ "out": "55e70b01d1fbf8b23b57fb62e26c2ce54f13f8fa2464e6eb98d16a6117026d8b90819012496d4071ebe2e59557ece3519a7aa45802f9615374877332b73490b3"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728",
+ "key": "",
+ "out": "25261eb296971d6e4a71b2928e64839c67d422872bf9f3c31993615222de9f8f0b2c4be8548559b4b354e736416e3218d4e8a1e219a4a6d43e1a9a521d0e75fc"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223242526272829",
+ "key": "",
+ "out": "08307f347c41294e34bb54cb42b1522d22f824f7b6e5db50fda096798e181a8f026fa27b4ae45d52a62caf9d5198e24a4913c6671775b2d723c1239bfbf016d7"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a",
+ "key": "",
+ "out": "1e5c62e7e9bfa1b118747a2de08b3ca10112af96a46e4b22c3fc06f9bfee4eb5c49e057a4a4886234324572576bb9b5ecfde0d99b0de4f98ec16e4d1b85fa947"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b",
+ "key": "",
+ "out": "c74a77395fb8bc126447454838e561e962853dc7eb49a1e3cb67c3d0851f3e39517be8c350ac910903d49cd2bfdf545c99316d0346170b739f0add5d533c2cfc"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c",
+ "key": "",
+ "out": "0dd57b423cc01eb2861391eb886a0d17079b933fc76eb3fc08a19f8a74952cb68f6bcdc644f77370966e4d13e80560bcf082ef0479d48fbbab4df03b53a4e178"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d",
+ "key": "",
+ "out": "4d8dc3923edccdfce70072398b8a3da5c31fcb3ee3b645c85f717cbaeb4b673a19394425a585bfb464d92f1597d0b754d163f97ced343b25db5a70ef48ebb34f"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e",
+ "key": "",
+ "out": "f0a50553e4dfb0c4e3e3d3ba82034857e3b1e50918f5b8a7d698e10d242b0fb544af6c92d0c3aaf9932220416117b4e78ecb8a8f430e13b82a5915290a5819c5"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f",
+ "key": "",
+ "out": "b15543f3f736086627cc5365e7e8988c2ef155c0fd4f428961b00d1526f04d6d6a658b4b8ed32c5d8621e7f4f8e8a933d9ecc9dd1b8333cbe28cfc37d9719e1c"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30",
+ "key": "",
+ "out": "7b4fa158e415fef023247264cbbe15d16d91a44424a8db707eb1e2033c30e9e1e7c8c0864595d2cb8c580eb47e9d16abbd7e44e824f7cedb7def57130e52cfe9"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031",
+ "key": "",
+ "out": "60424ff23234c34dc9687ad502869372cc31a59380186bc2361c835d972f49666eb1ac69629de646f03f9b4db9e2ace093fbfdf8f20ab5f98541978be8ef549f"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132",
+ "key": "",
+ "out": "7406018ce704d84f5eb9c79fea97da345699468a350ee0b2d0f3a4bf2070304ea862d72a51c57d3064947286f531e0eaf7563702262e6c724abf5ed8c8398d17"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233",
+ "key": "",
+ "out": "14ef5c6d647b3bd1e6e32006c231199810de5c4dc88e70240273b0ea18e651a3eb4f5ca3114b8a56716969c7cda27e0c8db832ad5e89a2dc6cb0adbe7d93abd1"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334",
+ "key": "",
+ "out": "38cf6c24e3e08bcf1f6cf3d1b1f65b905239a3118033249e448113ec632ea6dc346feeb2571c38bd9a7398b2221280328002b23e1a45adaffe66d93f6564eaa2"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435",
+ "key": "",
+ "out": "6cd7208a4bc7e7e56201bbba02a0f489cd384abe40afd4222f158b3d986ee72a54c50fb64fd4ed2530eda2c8af2928a0da6d4f830ae1c9db469dfd970f12a56f"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233343536",
+ "key": "",
+ "out": "659858f0b5c9edab5b94fd732f6e6b17c51cc096104f09beb3afc3aa467c2ecf885c4c6541effa9023d3b5738ae5a14d867e15db06fe1f9d1127b77e1aabb516"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637",
+ "key": "",
+ "out": "26cca0126f5d1a813c62e5c71001c046f9c92095704550be5873a495a999ad010a4f79491f24f286500adce1a137bc2084e4949f5b7294cefe51ecaff8e95cba"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738",
+ "key": "",
+ "out": "4147c1f55172788c5567c561feef876f621fff1ce87786b8467637e70dfbcd0dbdb6415cb600954ab9c04c0e457e625b407222c0fe1ae21b2143688ada94dc58"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233343536373839",
+ "key": "",
+ "out": "5b1bf154c62a8af6e93d35f18f7f90abb16a6ef0e8d1aecd118bf70167bab2af08935c6fdc0663ce74482d17a8e54b546d1c296631c65f3b522a515839d43d71"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a",
+ "key": "",
+ "out": "9f600419a4e8f4fb834c24b0f7fc13bf4e279d98e8a3c765ee934917403e3a66097182ea21453cb63ebbe8b73a9c2167596446438c57627f330badd4f569f7d6"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b",
+ "key": "",
+ "out": "457ef6466a8924fd8011a34471a5a1ac8ccd9bd0d07a97414ac943021ce4b9e4b9c8db0a28f016ed43b1542481990022147b313e194671131e708dd43a3ed7dc"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c",
+ "key": "",
+ "out": "9997b2194d9af6dfcb9143f41c0ed83d3a3f4388361103d38c2a49b280a581212715fd908d41c651f5c715ca38c0ce2830a37e00e508ced1bcdc320e5e4d1e2e"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d",
+ "key": "",
+ "out": "5c6bbf16baa180f986bd40a1287ed4c549770e7284858fc47bc21ab95ebbf3374b4ee3fd9f2af60f3395221b2acc76f2d34c132954049f8a3a996f1e32ec84e5"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e",
+ "key": "",
+ "out": "d10bf9a15b1c9fc8d41f89bb140bf0be08d2f3666176d13baac4d381358ad074c9d4748c300520eb026daeaea7c5b158892fde4e8ec17dc998dcd507df26eb63"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "key": "",
+ "out": "2fc6e69fa26a89a5ed269092cb9b2a449a4409a7a44011eecad13d7c4b0456602d402fa5844f1a7a758136ce3d5d8d0e8b86921ffff4f692dd95bdc8e5ff0052"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40",
+ "key": "",
+ "out": "fcbe8be7dcb49a32dbdf239459e26308b84dff1ea480df8d104eeff34b46fae98627b450c2267d48c0946a697c5b59531452ac0484f1c84e3a33d0c339bb2e28"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f4041",
+ "key": "",
+ "out": "a19093a6e3bcf5952f850f2030f69b9606f147f90b8baee3362da71d9f35b44ef9d8f0a7712ba1877fddcd2d8ea8f1e5a773d0b745d4725605983a2de901f803"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142",
+ "key": "",
+ "out": "3c2006423f73e268fa59d2920377eb29a4f9a8b462be15983ee3b85ae8a78e992633581a9099893b63db30241c34f643027dc878279af5850d7e2d4a2653073a"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243",
+ "key": "",
+ "out": "d0f2f2e3787653f77cce2fa24835785bbd0c433fc779465a115149905a9dd1cb827a628506d457fcf124a0c2aef9ce2d2a0a0f63545570d8667ff9e2eba07334"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f4041424344",
+ "key": "",
+ "out": "78a9fc048e25c6dcb5de45667de8ffdd3a93711141d594e9fa62a959475da6075ea8f0916e84e45ad911b75467077ee52d2c9aebf4d58f20ce4a3a00458b05d4"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445",
+ "key": "",
+ "out": "45813f441769ab6ed37d349ff6e72267d76ae6bb3e3c612ec05c6e02a12af5a37c918b52bf74267c3f6a3f183a8064ff84c07b193d08066789a01accdb6f9340"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243444546",
+ "key": "",
+ "out": "956da1c68d83a7b881e01b9a966c3c0bf27f68606a8b71d457bd016d4c41dd8a380c709a296cb4c6544792920fd788835771a07d4a16fb52ed48050331dc4c8b"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f4041424344454647",
+ "key": "",
+ "out": "df186c2dc09caa48e14e942f75de5ac1b7a21e4f9f072a5b371e09e07345b0740c76177b01278808fec025eded9822c122afd1c63e6f0ce2e32631041063145c"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748",
+ "key": "",
+ "out": "87475640966a9fdcd6d3a3b5a2cca5c08f0d882b10243c0ec1bf3c6b1c37f2cd3212f19a057864477d5eaf8faed73f2937c768a0af415e84bbce6bd7de23b660"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243444546474849",
+ "key": "",
+ "out": "c3b573bbe10949a0fbd4ff884c446f2229b76902f9dfdbb8a0353da5c83ca14e8151bbaac82fd1576a009adc6f1935cf26edd4f1fb8da483e6c5cd9d8923adc3"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a",
+ "key": "",
+ "out": "b09d8d0bba8a7286e43568f7907550e42036d674e3c8fc34d8ca46f771d6466b70fb605875f6a863c877d12f07063fdc2e90ccd459b1910dcd52d8f10b2b0a15"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b",
+ "key": "",
+ "out": "af3a22bf75b21abfb0acd54422ba1b7300a952eff02ebeb65b5c234471a98df32f4f9643ce1904108a168767924280bd76c83f8c82d9a79d9259b195362a2a04"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c",
+ "key": "",
+ "out": "bf4ff2221b7e6957a724cd964aa3d5d0d9941f540413752f4699d8101b3e537508bf09f8508b317736ffd265f2847aa7d84bd2d97569c49d632aed9945e5fa5e"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d",
+ "key": "",
+ "out": "9c6b6b78199b1bdacb4300e31479fa622a6b5bc80d4678a6078f88a8268cd7206a2799e8d4621a464ef6b43dd8adffe97caf221b22b6b8778b149a822aefbb09"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e",
+ "key": "",
+ "out": "890656f09c99d280b5ecb381f56427b813751bc652c7828078b23a4af83b4e3a61fdbac61f89bee84ea6bee760c047f25c6b0a201c69a38fd6fd971af18588bb"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f",
+ "key": "",
+ "out": "31a046f7882ffe6f83ce472e9a0701832ec7b3f76fbcfd1df60fe3ea48fde1651254247c3fd95e100f9172731e17fd5297c11f4bb328363ca361624a81af797c"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50",
+ "key": "",
+ "out": "27a60b2d00e7a671d47d0aec2a686a0ac04b52f40ab6629028eb7d13f4baa99ac0fe46ee6c814944f2f4b4d20e9378e4847ea44c13178091e277b87ea7a55711"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f5051",
+ "key": "",
+ "out": "8b5ccef194162c1f19d68f91e0b0928f289ec5283720840c2f73d253111238dcfe94af2b59c2c1ca2591901a7bc060e7459b6c47df0f71701a35cc0aa831b5b6"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152",
+ "key": "",
+ "out": "57ab6c4b2229aeb3b70476d803cd63812f107ce6da17fed9b17875e8f86c724f49e024cbf3a1b8b119c50357652b81879d2ade2d588b9e4f7cedba0e4644c9ee"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253",
+ "key": "",
+ "out": "0190a8dac320a739f322e15731aa140ddaf5bed294d5c82e54fef29f214e18aafaa84f8be99af62950266b8f901f15dd4c5d35516fc35b4cab2e96e4695bbe1c"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f5051525354",
+ "key": "",
+ "out": "d14d7c4c415eeb0e10b159224bea127ebd84f9591c702a330f5bb7bb7aa44ea39de6ed01f18da7adf40cfb97c5d152c27528824b21e239526af8f36b214e0cfb"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455",
+ "key": "",
+ "out": "be28c4be706970488fac7d29c3bd5c4e986085c4c3332f1f3fd30973db614164ba2f31a78875ffdc150325c88327a9443ed04fdfe5be93876d1628560c764a80"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253545556",
+ "key": "",
+ "out": "031da1069e3a2e9c3382e436ffd79df74b1ca6a8adb2deabe676ab45994cbc054f037d2f0eace858d32c14e2d1c8b46077308e3bdc2c1b53172ecf7a8c14e349"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f5051525354555657",
+ "key": "",
+ "out": "4665cef8ba4db4d0acb118f2987f0bb09f8f86aa445aa3d5fc9a8b346864787489e8fcecc125d17e9b56e12988eac5ecc7286883db0661b8ff05da2afff30fe4"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758",
+ "key": "",
+ "out": "63b7032e5f930cc9939517f9e986816cfbec2be59b9568b13f2ead05bae7777cab620c6659404f7409e4199a3be5f7865aa7cbdf8c4253f7e8219b1bd5f46fea"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253545556575859",
+ "key": "",
+ "out": "9f09bf093a2b0ff8c2634b49e37f1b2135b447aa9144c9787dbfd92129316c99e88aab8a21fdef2372d1189aec500f95775f1f92bfb45545e4259fb9b7b02d14"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a",
+ "key": "",
+ "out": "f9f8493c68088807df7f6a2693d64ea59f03e9e05a223e68524ca32195a4734b654fcea4d2734c866cf95c889fb10c49159be2f5043dc98bb55e02ef7bdcb082"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b",
+ "key": "",
+ "out": "3c9a7359ab4febce07b20ac447b06a240b7fe1dae5439c49b60b5819f7812e4c172406c1aac316713cf0dded1038077258e2eff5b33913d9d95caeb4e6c6b970"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c",
+ "key": "",
+ "out": "ad6aab8084510e822cfce8625d62cf4de655f4763884c71e80bab9ac9d5318dba4a6033ed29084e65216c031606ca17615dcfe3ba11d26851ae0999ca6e232cf"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d",
+ "key": "",
+ "out": "156e9e6261374c9dc884f36e70f0fe1ab9297997b836fa7d170a9c9ebf575b881e7bcea44d6c0248d35597907154828955be19135852f9228815eca024a8adfb"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e",
+ "key": "",
+ "out": "4215407633f4cca9b6788be93e6aa3d963c7d6ce4b147247099f46a3acb500a30038cb3e788c3d29f132ad844e80e9e99251f6db96acd8a091cfc770af53847b"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
+ "key": "",
+ "out": "1c077e279de6548523502b6df800ffdab5e2c3e9442eb838f58c295f3b147cef9d701c41c321283f00c71affa0619310399126295b78dd4d1a74572ef9ed5135"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60",
+ "key": "",
+ "out": "f07a555f49fe481cf4cd0a87b71b82e4a95064d06677fdd90a0eb598877ba1c83d4677b393c3a3b6661c421f5b12cb99d20376ba7275c2f3a8f5a9b7821720da"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f6061",
+ "key": "",
+ "out": "b5911b380d20c7b04323e4026b38e200f534259233b581e02c1e3e2d8438d6c66d5a4eb201d5a8b75072c4ec29106334da70bc79521b0ced2cfd533f5ff84f95"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162",
+ "key": "",
+ "out": "01f070a09bae911296361f91aa0e8e0d09a7725478536d9d48c5fe1e5e7c3c5b9b9d6eb07796f6da57ae562a7d70e882e37adfde83f0c433c2cd363536bb22c8"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60616263",
+ "key": "",
+ "out": "6f793eb4374a48b0775acaf9adcf8e45e54270c9475f004ad8d5973e2aca52747ff4ed04ae967275b9f9eb0e1ff75fb4f794fa8be9add7a41304868d103fab10"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f6061626364",
+ "key": "",
+ "out": "965f20f139765fcc4ce4ba3794675863cac24db472cd2b799d035bce3dbea502da7b524865f6b811d8c5828d3a889646fe64a380da1aa7c7044e9f245dced128"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465",
+ "key": "",
+ "out": "ec295b5783601244c30e4641e3b45be222c4dce77a58700f53bc8ec52a941690b4d0b087fb6fcb3f39832b9de8f75ec20bd43079811749cdc907edb94157d180"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60616263646566",
+ "key": "",
+ "out": "61c72f8ccc91dbb54ca6750bc489672de09faedb8fdd4f94ff2320909a303f5d5a98481c0bc1a625419fb4debfbf7f8a53bb07ec3d985e8ea11e72d559940780"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f6061626364656667",
+ "key": "",
+ "out": "afd8145b259eefc8d12620c3c5b03e1ed8fd2ccefe0365078c80fd42c1770e28b44948f27e65a1886690110db814397b68e43d80d1ba16dfa358e739c898cfa3"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768",
+ "key": "",
+ "out": "552fc7893cf1ce933ada35c0da98844e41545e244c3157a1428d7b4c21f9cd7e4071aed77b7ca9f1c38fba32237412ef21a342742ec8324378f21e507fafdd88"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60616263646566676869",
+ "key": "",
+ "out": "467a33fbadf5ebc52596ef86aaaefc6faba8ee651b1ce04de368a03a5a9040ef2835e00adb09abb3fbd2bce818a2413d0b0253b5bda4fc5b2f6f85f3fd5b55f2"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a",
+ "key": "",
+ "out": "22eff8e6dd5236f5f57d94ede874d6c9428e8f5d566f17cd6d1848cd752fe13c655cb10fbaaff76872f2bf2da99e15dc624075e1ec2f58a3f64072121838569e"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b",
+ "key": "",
+ "out": "9cec6bbf62c4bce4138abae1cbec8dad31950444e90321b1347196834c114b864af3f3cc3508f83751ffb4eda7c84d140734bb4263c3625c00f04f4c8068981b"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c",
+ "key": "",
+ "out": "a8b60fa4fc2442f6f1514ad7402626920cc7c2c9f72124b8cba8ee2cb7c4586f658a4410cffcc0ab88343955e094c6af0d20d0c714fb0a988f543f300f58d389"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d",
+ "key": "",
+ "out": "8271cc45dfa5e4170e847e8630b952cf9c2aa777d06f26a7585b8381f188dacc7337391cfcc94b053dc4ec29cc17f077870428f1ac23fddda165ef5a3f155f39"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e",
+ "key": "",
+ "out": "bf23c0c25c8060e4f6995f1623a3bebecaa96e308680000a8aa3cd56bb1a6da099e10d9231b37f4519b2efd2c24de72f31a5f19535241b4a59fa3c03ceb790e7"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f",
+ "key": "",
+ "out": "877fd652c05281009c0a5250e7a3a671f8b18c108817fe4a874de22da8e45db11958a600c5f62e67d36cbf84474cf244a9c2b03a9fb9dc711cd1a2cab6f3fae0"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f70",
+ "key": "",
+ "out": "29df4d87ea444baf5bcdf5f4e41579e28a67de84149f06c03f110ea84f572a9f676addd04c4878f49c5c00accda441b1a387caceb2e993bb7a10cd8c2d6717e1"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f7071",
+ "key": "",
+ "out": "710dacb166844639cd7b637c274209424e2449dc35d790bbfa4f76177054a36b3b76fac0ca6e61df1e687000678ac0746df75d0a3954897681fd393a155a1bb4"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172",
+ "key": "",
+ "out": "c1d5f93b8dea1f2571babccbc01764541a0cda87e444d673c50966ca559c33354b3acb26e5d5781ffb28847a4b4754d77008c62a835835f500dea7c3b58bdae2"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f70717273",
+ "key": "",
+ "out": "a41e41271cdab8af4d72b104bfb2ad041ac4df14677da671d85640c4b187f50c2b66513c4619fbd5d5dc4fe65dd37b9042e9848dda556a504caa2b1c6afe4730"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f7071727374",
+ "key": "",
+ "out": "e7bcbacdc379c43d81ebadcb37781552fc1d753e8cf310d968392d06c91f1d64cc9e90ce1d22c32d277fc6cda433a4d442c762e9eacf2c259f32d64cf9da3a22"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475",
+ "key": "",
+ "out": "51755b4ac5456b13218a19c5b9242f57c4a981e4d4ecdce09a3193362b808a579345d4881c2607a56534dd7f21956aff72c2f4173a6e7b6cc2212ba0e3daee1f"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f70717273747576",
+ "key": "",
+ "out": "dcc2c4beb9c1f2607b786c20c631972347034c1cc02fcc7d02ff01099cfe1c6989840ac213923629113aa8bad713ccf0fe4ce13264fb32b8b0fe372da382544a"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f7071727374757677",
+ "key": "",
+ "out": "3d55176acea4a7e3a65ffa9fb10a7a1767199cf077cee9f71532d67cd7c73c9f93cfc37ccdcc1fdef50aad46a504a650d298d597a3a9fa95c6c40cb71fa5e725"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778",
+ "key": "",
+ "out": "d07713c005de96dd21d2eb8bbeca66746ea51a31ae922a3e74864889540a48db27d7e4c90311638b224bf0201b501891754848113c266108d0adb13db71909c7"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f70717273747576777879",
+ "key": "",
+ "out": "58983c21433d950caa23e4bc18543b8e601c204318532152daf5e159a0cd1480183d29285c05f129cb0cc3164687928086ffe380158df1d394c6ac0d4288bca8"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a",
+ "key": "",
+ "out": "8100a8dc528d2b682ab4250801ba33f02a3e94c54dac0ae1482aa21f51ef3a82f3807e6facb0aeb05947bf7aa2adcb034356f90fa4560ede02201a37e411ec1a"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b",
+ "key": "",
+ "out": "07025f1bb6c784f3fe49de5c14b936a5acacacaab33f6ac4d0e00ab6a12483d6bec00b4fe67c7ca5cc508c2a53efb5bfa5398769d843ff0d9e8b14d36a01a77f"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c",
+ "key": "",
+ "out": "ba6aefd972b6186e027a76273a4a723321a3f580cfa894da5a9ce8e721c828552c64dacee3a7fd2d743b5c35ad0c8efa71f8ce99bf96334710e2c2346e8f3c52"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d",
+ "key": "",
+ "out": "e0721e02517aedfa4e7e9ba503e025fd46e714566dc889a84cbfe56a55dfbe2fc4938ac4120588335deac8ef3fa229adc9647f54ad2e3472234f9b34efc46543"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e",
+ "key": "",
+ "out": "b6292669ccd38d5f01caae96ba272c76a879a45743afa0725d83b9ebb26665b731f1848c52f11972b6644f554c064fa90780dbbbf3a89d4fc31f67df3e5857ef"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f",
+ "key": "",
+ "out": "2319e3789c47e2daa5fe807f61bec2a1a6537fa03f19ff32e87eecbfd64b7e0e8ccff439ac333b040f19b0c4ddd11a61e24ac1fe0f10a039806c5dcc0da3d115"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80",
+ "key": "",
+ "out": "f59711d44a031d5f97a9413c065d1e614c417ede998590325f49bad2fd444d3e4418be19aec4e11449ac1a57207898bc57d76a1bcf3566292c20c683a5c4648f"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f8081",
+ "key": "",
+ "out": "df0a9d0c212843a6a934e3902b2dd30d17fba5f969d2030b12a546d8a6a45e80cf5635f071f0452e9c919275da99bed51eb1173c1af0518726b75b0ec3bae2b5"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182",
+ "key": "",
+ "out": "a3eb6e6c7bf2fb8b28bfe8b15e15bb500f781ecc86f778c3a4e655fc5869bf2846a245d4e33b7b14436a17e63be79b36655c226a50ffbc7124207b0202342db5"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80818283",
+ "key": "",
+ "out": "56d4cbcd070563426a017069425c2cd2ae540668287a5fb9dac432eb8ab1a353a30f2fe1f40d83333afe696a267795408a92fe7da07a0c1814cf77f36e105ee8"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f8081828384",
+ "key": "",
+ "out": "e59b9987d428b3eda37d80abdb16cd2b0aef674c2b1dda4432ea91ee6c935c684b48b4428a8cc740e579a30deff35a803013820dd23f14ae1d8413b5c8672aec"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485",
+ "key": "",
+ "out": "cd9fcc99f99d4cc16d031900b2a736e1508db4b586814e6345857f354a70ccecb1df3b50a19adaf43c278efa423ff4bb6c523ec7fd7859b97b168a7ebff8467c"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80818283848586",
+ "key": "",
+ "out": "0602185d8c3a78738b99164b8bc6ffb21c7debebbf806372e0da44d121545597b9c662a255dc31542cf995ecbe6a50fb5e6e0ee4ef240fe557eded1188087e86"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f8081828384858687",
+ "key": "",
+ "out": "c08afa5b927bf08097afc5fff9ca4e7800125c1f52f2af3553fa2b89e1e3015c4f87d5e0a48956ad31450b083dad147ffb5ec03434a26830cf37d103ab50c5da"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788",
+ "key": "",
+ "out": "36f1e1c11d6ef6bc3b536d505d544a871522c5c2a253067ec9933b6ec25464daf985525f5b9560a16d890259ac1bb5cc67c0c469cde133def000ea1d686f4f5d"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80818283848586878889",
+ "key": "",
+ "out": "bf2ab2e2470f5438c3b689e66e7686fffa0cb1e1798ad3a86ff99075bf6138e33d9c0ce59afb24ac67a02af34428191a9a0a6041c07471b7c3b1a752d6fc0b8b"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a",
+ "key": "",
+ "out": "d400601f9728ccc4c92342d9787d8d28ab323af375ca5624b4bb91d17271fbae862e413be73f1f68e615b8c5c391be0dbd9144746eb339ad541547ba9c468a17"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b",
+ "key": "",
+ "out": "79fe2fe157eb85a038abb8ebbc647731d2c83f51b0ac6ee14aa284cb6a3549a4dcceb300740a825f52f5fb30b03b8c4d8b0f4aa67a63f4a94e3303c4eda4c02b"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c",
+ "key": "",
+ "out": "75351313b52a8529298d8c186b1768666dcca8595317d7a4816eb88c062020c0c8efc554bb341b64688db5ccafc35f3c3cd09d6564b36d7b04a248e146980d4b"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d",
+ "key": "",
+ "out": "e3128b1d311d02179d7f25f97a5a8bee2cc8c86303644fcd664e157d1fef00f23e46f9a5e8e5c890ce565bb6abd4302ce06469d52a5bd53e1c5a54d04649dc03"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e",
+ "key": "",
+ "out": "c2382a72d2d3ace9d5933d00b60827ed380cda08d0ba5f6dd41e29ee6dbe8ecb9235f06be95d83b6816a2fb7a5ad47035e8a4b69a4884b99e4bece58cab25d44"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f",
+ "key": "",
+ "out": "6b1c69460bbd50ac2ed6f32e6e887cfed407d47dcf0aaa60387fe320d780bd03eab6d7baeb2a07d10cd552a300341354ea9a5f03183a623f92a2d4d9f00926af"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f90",
+ "key": "",
+ "out": "6cda206c80cdc9c44ba990e0328c314f819b142d00630404c48c05dc76d1b00ce4d72fc6a48e1469ddef609412c364820854214b4869af090f00d3c1ba443e1b"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f9091",
+ "key": "",
+ "out": "7ffc8c26fbd6a0f7a609e6e1939f6a9edf1b0b066641fb76c4f9602ed748d11602496b35355b1aa255850a509d2f8ee18c8f3e1d7dcbc37a136598f56a59ed17"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192",
+ "key": "",
+ "out": "70de1f08dd4e09d5fc151f17fc991a23abfc05104290d50468882efaf582b6ec2f14f577c0d68c3ad06626916e3c86e6daab6c53e5163e82b6bd0ce49fc0d8df"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f90919293",
+ "key": "",
+ "out": "4f81935756ed35ee2058ee0c6a6110d6fac5cb6a4f46aa9411603f99965823b6da4838276c5c06bc7880e376d92758369ee7305bcec8d3cfd28ccabb7b4f0579"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f9091929394",
+ "key": "",
+ "out": "abcb61cb3683d18f27ad527908ed2d32a0426cb7bb4bf18061903a7dc42e7e76f982382304d18af8c80d91dd58dd47af76f8e2c36e28af2476b4bccf82e89fdf"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495",
+ "key": "",
+ "out": "02d261ad56a526331b643dd2186de9a82e72a58223cd1e723686c53d869b83b94632b7b647ab2afc0d522e29da3a5615b741d82852e0df41b66007dbcba90543"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f90919293949596",
+ "key": "",
+ "out": "c5832741fa30c5436823015383d297ff4c4a5d7276c3f902122066e04be5431b1a85faf73b918434f9300963d1dea9e8ac3924ef490226edeea5f743e410669f"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f9091929394959697",
+ "key": "",
+ "out": "cfaeab268cd075a5a6aed515023a032d54f2f2ff733ce0cbc78db51db4504d675923f82746d6594606ad5d67734b11a67cc6a468c2032e43ca1a94c6273a985e"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798",
+ "key": "",
+ "out": "860850f92eb268272b67d133609bd64e34f61bf03f4c1738645c17fec818465d7ecd2be2907641130025fda79470ab731646e7f69440e8367ea76ac4cee8a1df"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f90919293949596979899",
+ "key": "",
+ "out": "84b154ed29bbedefa648286839046f4b5aa34430e2d67f7496e4c39f2c7ea78995f69e1292200016f16ac3b37700e6c7e7861afc396b64a59a1dbf47a55c4bbc"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a",
+ "key": "",
+ "out": "aeeec260a5d8eff5ccab8b95da435a63ed7a21ea7fc7559413fd617e33609f8c290e64bbacc528f6c080262288b0f0a3219be223c991bee92e72349593e67638"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b",
+ "key": "",
+ "out": "8ad78a9f26601d127e8d2f2f976e63d19a054a17dcf59e0f013ab54a6887bbdffde7aaae117e0fbf3271016595b9d9c712c01b2c53e9655a382bc4522e616645"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c",
+ "key": "",
+ "out": "8934159dade1ac74147dfa282c75954fcef443ef25f80dfe9fb6ea633b8545111d08b34ef43fff17026c7964f5deac6d2b3c29dacf2747f022df5967dfdc1a0a"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d",
+ "key": "",
+ "out": "cd36dd0b240614cf2fa2b9e959679dcdd72ec0cd58a43da3790a92f6cdeb9e1e795e478a0a47d371100d340c5cedcdbbc9e68b3f460818e5bdff7b4cda4c2744"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e",
+ "key": "",
+ "out": "00df4e099b807137a85990f49d3a94315e5a5f7f7a6076b303e96b056fb93800111f479628e2f8db59aeb6ac70c3b61f51f9b46e80ffdeae25ebddb4af6cb4ee"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "key": "",
+ "out": "2b9c955e6caed4b7c9e246b86f9a1726e810c59d126cee66ed71bf015b83558a4b6d84d18dc3ff4620c2ffb722359fdef85ba0d4e2d22ecbe0ed784f99afe587"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0",
+ "key": "",
+ "out": "181df0a261a2f7d29ea5a15772715105d450a4b6c236f699f462d60ca76487feedfc9f5eb92df838e8fb5dc3694e84c5e0f4a10b761f506762be052c745a6ee8"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1",
+ "key": "",
+ "out": "21fb203458bf3a7e9a80439f9a902899cd5de0139dfd56f7110c9dec8437b26bda63de2f565926d85edb1d6c6825669743dd9992653d13979544d5dc8228bfaa"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2",
+ "key": "",
+ "out": "ef021f29c5ffb830e64b9aa9058dd660fd2fcb81c497a7e698bcfbf59de5ad4a86ff93c10a4b9d1ae5774725f9072dcde9e1f199bab91f8bff921864aa502eee"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3",
+ "key": "",
+ "out": "b3cfda40526b7f1d37569bdfcdf911e5a6efe6b2ec90a0454c47b2c046bf130fc3b352b34df4813d48d33ab8e269b69b075676cb6d00a8dcf9e1f967ec191b2c"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4",
+ "key": "",
+ "out": "b4c6c3b267071eefb9c8c72e0e2b941293641f8673cb70c1cc26ad1e73cf141755860ad19b34c2f34ed35bb52ec4507cc1fe59047743a5f0c6febde625e26091"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5",
+ "key": "",
+ "out": "57a34f2bcca60d4b85103b830c9d7952a416be5263ae429c9e5e53fe8590a8f78ec65a51109ea85dcdf7b6223f9f2b340539fad81923dbf8edabf95129e4dff6"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6",
+ "key": "",
+ "out": "9cf46662fcd61a232277b685663b8b5da832dfd9a3b8ccfeec993ec6ac415ad07e048adfe414df272770dba867da5c1224c6fd0aa0c2187d426ac647e9887361"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7",
+ "key": "",
+ "out": "5ce1042ab4d542c2f9ee9d17262af8164098935bef173d0e18489b04841746cd2f2df866bd7da6e5ef9024c648023ec723ab9c62fd80285739d84f15d2ab515a"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8",
+ "key": "",
+ "out": "8488396bd4a8729b7a473178f232dadf3f0f8e22678ba5a43e041e72da1e2cf82194c307207a54cb8156293339eaec693ff66bfcd5efc65e95e4ecaf54530abd"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9",
+ "key": "",
+ "out": "f598da901c3835bca560779037dfde9f0c51dc61c0b760fc1522d7b470ee63f5bdc6498476e86049ad86e4e21af2854a984cc905427d2f17f66b1f41c3da6f61"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aa",
+ "key": "",
+ "out": "5f93269798cf02132107337660a8d7a177354c0212eb93e555e7c37a08aef3d8dce01217011cd965c04dd2c105f2e2b6cae5e4e6bcaf09dfbee3e0a6a6357c37"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaab",
+ "key": "",
+ "out": "0ecf581d47bac9230986faabd70c2f5b80e91066f0ec55a842937882286d2ca007bb4e973b0b091d52167ff7c4009c7ab4ad38fff1dceacdb7be81ef4a452952"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabac",
+ "key": "",
+ "out": "5aeca8abe1528582b2a307b4009585498a3d467ca6101cb0c5126f9976056e9ffc123cc20c302b2a737f492c75d21f01512c90ca0541dfa56e950a321dcb28d8"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacad",
+ "key": "",
+ "out": "732fbf8f1cb2b8329263ede27858fe46f8d3354d376bcda0548e7ce1fa9dd11f85eb661fe950b543aa635ca4d3f04ede5b32d6b656e5ce1c44d35c4a6c56cff8"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadae",
+ "key": "",
+ "out": "d5e938735d63788c80100aefd18648d18cf272f69f20ff24cfe2895c088ad08b0104da1672a4eb26fc52545cc7d7a01b266cf546c403c45bd129eb41bdd9200b"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf",
+ "key": "",
+ "out": "65a245b49352ee297d91af8c8be00528ac6e046dd83ac7bd465a98816dd68f3e00e1ae8f895327a7e9a8c9326598379a29c9fc91ec0c6eef08f3e2b216c11008"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0",
+ "key": "",
+ "out": "c95654b63019130ab45dd0fb4941b98aeb3af2a123913eca2ce99b3e97410a7bf8661cc7fbaa2bc1cf2b13113b1ed40a0118b88e5fffc3542759ea007ed4c58d"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1",
+ "key": "",
+ "out": "1eb262f38fa494431f017dad44c0dfb69324ac032f04b657fc91a88647bb74760f24e7c956514f0cf002990b182c1642b9b2426e96a61187e4e012f00e217d84"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2",
+ "key": "",
+ "out": "3b955aeebfa5151ac1ab8e3f5cc1e3767084c842a575d36269836e97353d41622b731dddcd5f269550a3a5b87be1e90326340b6e0e62555815d9600597ac6ef9"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3",
+ "key": "",
+ "out": "68289f6605473ba0e4f241baf7477a9885426a858f19ef2a18b0d40ef8e41282ed5526b519799e270f13881327918278755711071d8511fe963e3b5606aa3716"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4",
+ "key": "",
+ "out": "80a33787542612c38f6bcd7cd86cab460227509b1cbad5ec408a91413d51155a0476dadbf3a2518e4a6e77cc346622e347a469bf8baa5f04eb2d98705355d063"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5",
+ "key": "",
+ "out": "34629bc6d831391c4cdf8af1b4b7b6b8e8ee17cf98c70e5dd586cd99f14b11df945166236a9571e6d591bb83ee4d164d46f6b9d8ef86ff865a81bfb91b00424b"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6",
+ "key": "",
+ "out": "8b7cc339163863bb4383e542b0ef0e7cf36b84ad932cdf5a80419ec9ad692e7a7e784d2c7cb3796a18b8f800035f3aa06c824100611120a7bdeb35618ccb81b7"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7",
+ "key": "",
+ "out": "4f084e4939dd5a7f5a658fad58a18a15c25c32ec1c7fd5c5c6c3e892b3971aeaac308304ef17b1c47239ea4bb398b3fd6d4528d8de8e768ae0f1a5a5c6b5c297"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8",
+ "key": "",
+ "out": "48f407a1af5b8009b2051742e8cf5cd5656669e7d722ee8e7bd202060849442168d8facc117c012bfb7bf449d99befff6a34aea203f1d8d352722be5014ec818"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9",
+ "key": "",
+ "out": "a6aa82cd1e426f9a73bfa39a29037876114655b8c22d6d3ff8b638ae7dea6b17843e09e52eb66fa1e475e4a8a3de429b7d0f4a776fcb8bdc9b9fede7d52e815f"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9ba",
+ "key": "",
+ "out": "5817027d6bdd00c5dd10ac593cd560372270775a18526d7e6f13872a2e20eab664625be7168ac4bd7c9e0ce7fc4099e0f48442e2c767191c6e1284e9b2ccea8c"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babb",
+ "key": "",
+ "out": "08e41028340a45c74e4052b3a8d6389e22e043a1adab5e28d97619450d723469b620caa519b81c14523854f619fd3027e3847bd03276e60604a80ddb4de876d6"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbc",
+ "key": "",
+ "out": "130b8420537eb07d72abda07c85acbd8b9a44f16321dd0422145f809673d30f2b5321326e2bff317ef3fef983c51c4f8ab24a325d298e34afce569a82555774c"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbd",
+ "key": "",
+ "out": "ac49b844afaa012e31c474ca263648844fd2f6307992c2f752aca02c3828965175794deee2d2ee95c61cd284f6b5a2d75e2ef2b29ee8149e77fb81447b2fd04b"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbe",
+ "key": "",
+ "out": "b9d7ca81cc60bb9578e44024e5a0a0be80f27336a6a9f4e53df3999cb191280b090e2ac2d29c5baad9d71415bdc129e69aa2667af6a7fd5e189fccdcee817340"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf",
+ "key": "",
+ "out": "a755e113386572c75ced61d719706070b9146048e42a9f8cd35667a088b42f08808abdf77e618abd959afc757379ca2c00bcc1a48390fa2bff618b1e0078a613"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0",
+ "key": "",
+ "out": "a73c7debed326f1c0db0795ee7d6e3946894b826b1f8101c56c823ba17168312e7f53fc7dbe52c3e11e69852c40485e2ef182477862ea6a34ec136e2dfeea6f4"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1",
+ "key": "",
+ "out": "6cb8f9d52c56d82cac28f39ea1593e8bb2506293ac0d68376a1709b62a46df14a4ae64b2d8fab76733a1ced2d548e3f3c6fcb49d40c3d5808e449cd83d1c2aa2"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2",
+ "key": "",
+ "out": "683fa2b2369a10162c1c1c7b24bc970ee67da220564f32203f625696c0352a0b9ad96624362d952d84463c1106a2dba7a092599884b35a0b89c8f1b6a9b5a61e"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3",
+ "key": "",
+ "out": "aad9ad44610118b77d508aeb1bbcd1c1b7d0171397fb510a401bbc0ec34623670d86a2dc3c8f3ab5a2044df730256727545f0860ce21a1eac717dfc48f5d228e"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4",
+ "key": "",
+ "out": "c42578de23b4c987d5e1ac4d689ed5de4b0417f9704bc6bce969fa13471585d62c2cb1212a944f397fc9ca2c3747c3beb694ec4c5be68828dda53ef43faec6c0"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5",
+ "key": "",
+ "out": "470f00841ee8244e63ed2c7ea30e2e419897c197462ecccecf713b42a5065fff5914bc9b79affe8f6b657875e789ae213bd914cd35bd174d46e9d18bd843773d"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6",
+ "key": "",
+ "out": "34fc4213730f47a5e9a3580f643e12945cfcb31bf206f6ad450ce528da3fa432e005d6b0ecce10dca7c5995f6aacc5150e1b009e19751e8309f8859531844374"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7",
+ "key": "",
+ "out": "fb3c1f0f56a56f8e316fdf5d853c8c872c39635d083634c3904fc3ac07d1b578e85ff0e480e92d44ade33b62e893ee32343e79ddf6ef292e89b582d312502314"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8",
+ "key": "",
+ "out": "c7c97fc65dd2b9e3d3d607d31598d3f84261e9919251e9c8e57bb5f829377d5f73eabbed55c6c381180f29ad02e5be797ffec7e57bdecbc50ad3d062f0993ab0"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9",
+ "key": "",
+ "out": "a57a49cdbe67ae7d9f797bb5cc7efc2df07f4e1b15955f85dae74b76e2ecb85afb6cd9eeed8888d5ca3ec5ab65d27a7b19e578475760a045ac3c92e13a938e77"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9ca",
+ "key": "",
+ "out": "c7143fce9614a17fd653aeb140726dc9c3dbb1de6cc581b2726897ec24b7a50359ad492243be66d9edd8c933b5b80e0b91bb61ea98056006516976fae8d99a35"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacb",
+ "key": "",
+ "out": "65bb58d07f937e2d3c7e65385f9c54730b704105ccdb691f6e146d4ee8f6c086f49511035110a9ad6031fdceb943e0f9613bcb276dd40f0624ef0f924f809783"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcc",
+ "key": "",
+ "out": "e540277f683b1186dd3b5b3f61433396581a35feb12002be8c6a6231fc40ffa70f08081bc58b2d94f7649543614a435faa2d62110e13dabc7b86629b63af9c24"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccd",
+ "key": "",
+ "out": "418500878c5fbcb584c432f4285e05e49f2e3e075399a0dbfcf874ebf8c03d02bf16bc6989d161c77ca0786b05053c6c709433712319192128835cf0b660595b"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdce",
+ "key": "",
+ "out": "889090dbb1944bdc9433ee5ef1010c7a4a24a8e71ecea8e12a31318ce49dcab0aca5c3802334aab2cc84b14c6b9321fe586bf3f876f19cd406eb1127fb944801"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecf",
+ "key": "",
+ "out": "53b6a28910aa92e27e536fb549cf9b9918791060898e0b9fe183577ff43b5e9c7689c745b32e412269837c31b89e6cc12bf76e13cad366b74ece48bb85fd09e9"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0",
+ "key": "",
+ "out": "7c092080c6a80d672409d081d3d177106bcd63567785140719490950ae07ae8fcaabbaaab330cfbcf7374482c220af2eadeeb73dcbb35ed823344e144e7d4899"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1",
+ "key": "",
+ "out": "9ccde566d2400509181111f32dde4cd63209fe59a30c114546ad2776d889a41bad8fa1bb468cb2f9d42ca9928a7770fef8e8ba4d0c812d9a1e75c3d8d2ccd75a"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2",
+ "key": "",
+ "out": "6e293bf5d03fe43977cfe3f57ccdb3ae282a85455dca33f37f4b74f8398cc612433d755cbec412f8f82a3bd3bc4a278f7ecd0dfa9bbdc40be7a787c8f159b2df"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3",
+ "key": "",
+ "out": "c56546fb2178456f336164c18b90deffc83ae2b5a3aca77b6884d36d2c1db39501b3e65e36c758c66e3188451fdb3515ee162c001f06c3e8cb573adf30f7a101"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4",
+ "key": "",
+ "out": "6f82f89f299ebca2fe014b59bffe1aa84e88b1915fe256afb646fd8448af2b8891a7fab37a4ea6f9a50e6c317039d8cf878f4c8e1a0dd464f0b4d6ff1c7ea853"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5",
+ "key": "",
+ "out": "2b8599ff9c3d6198637ad51e57d1998b0d75313fe2dd61a533c964a6dd9607c6f723e9452ce46e014b1c1d6de77ba5b88c914d1c597bf1eae13474b4290e89b2"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6",
+ "key": "",
+ "out": "08bf346d38e1df06c8260edb1da75579275948d5c0a0aa9ed2886f8856de5417a156998758f5b17e52f101ca957a71137473dfd18d7d209c4c10d9233c93691d"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7",
+ "key": "",
+ "out": "6df2156d773114d310b63db9ee5350d77e6bcf25b05fcd910f9b31bc42bb13fe8225ebcb2a23a62280777b6bf74e2cd0917c7640b43defe468cd1e18c943c66a"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8",
+ "key": "",
+ "out": "7c7038bc13a91151828a5ba82b4a96040f258a4dfb1b1373f0d359168afb0517a20b28a12d3644046be66b8d08d8ae7f6a923ea1c00187c6d11dc502bac71305"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9",
+ "key": "",
+ "out": "bcd1b30d808fb739b987cbf154bea00da9d40380b861d4c1d6377122dadd61c0e59018b71941cfb62e00dcd70aeb9abf0473e80f0a7eca6b6dea246ab229dd2b"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9da",
+ "key": "",
+ "out": "7ed4468d968530fe7ab2c33540b26d8c3bd3ed44b34fbe8c2a9d7f805b5ada0ea252eeade4fce97f89728ad85bc8bb2430b1bef2cddd32c8446e59b8e8ba3c67"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadb",
+ "key": "",
+ "out": "6d30b7c6ce8a3236c0ca2f8d728b1088ca06983a8043e621d5dcf0c537d13b08791edeb01a3cf0943ec1c890ab6e29b146a236cd46bcb9d93bf516fb67c63fe5"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdc",
+ "key": "",
+ "out": "97fe03cef31438508911bded975980a66029305dc5e3fa8ad1b4fb22fcdf5a19a733320327d8f71ccf496cb3a44a77af56e3dde73d3a5f176896cc57c9a5ad99"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdd",
+ "key": "",
+ "out": "785a9d0fbd21136dbce8fa7eafd63c9dad220052978416b31d9753eaa149097847ed9b30a65c70507eff01879149ed5cf0471d37798edc05abd56ad4a2cccb1d"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcddde",
+ "key": "",
+ "out": "ad408d2abddfd37b3bf34794c1a3371d928ed7fc8d966225333584c5665817832a37c07f0dc7cb5aa874cd7d20fe8fab8eabcb9b33d2e0841f6e200960899d95"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf",
+ "key": "",
+ "out": "97668f745b6032fc815d9579322769dccd9501a5080029b8ae826befb6742331bd9f76efeb3e2b8e81a9786b282f5068a3a2424697a77c41876b7e753f4c7767"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0",
+ "key": "",
+ "out": "26bb985f47e7fee0cfd252d4ef96bed42b9c370c1c6a3e8c9eb04ef7f7818b833a0d1f043ebafb911dc779e02740a02a44d3a1ea45ed4ad55e686c927cafe97e"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1",
+ "key": "",
+ "out": "5bfe2b1dcf7fe9b95088acedb575c19016c743b2e763bf5851ac407c9eda43715edfa48b4825492c5179593fff21351b76e8b7e034e4c53c79f61f29c479bd08"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2",
+ "key": "",
+ "out": "c76509ef72f4a6f9c9c40618ed52b2084f83502232e0ac8bdaf3264368e4d0180f6854c4abf4f6509c79caafc44cf3194afc57bd077bd7b3c9bda3d4b8775816"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3",
+ "key": "",
+ "out": "d66f2beab990e354ccb910e4e9c7ac618c7b63ef292a96b552341de78dc46d3ec8cfabc699b50af41fda39cf1b0173660923510ad67faedef5207cffe8641d20"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4",
+ "key": "",
+ "out": "7d8f0672992b79be3a364d8e5904f4ab713bbc8ab01b4f309ad8ccf223ce1034a860dcb0b00550612cc2fa17f2969e18f22e1427d254b4a82b3a03a3eb394adf"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5",
+ "key": "",
+ "out": "a56d6725bfb3de47c1414adf25fc8f0fc9846f6987722bc06366d5ca4e89722925ebbc881418844075397a0ca89842c7b9e9e07e1d9d183ebeb39e120b483bf7"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6",
+ "key": "",
+ "out": "af5e03d7fe60c67e10313344434e79485a03a758d6dce985574745763c1c5c77d4fb3e6fb12230368370993bf90feed0c5d1607524562d7c09c0c210ed393d7c"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7",
+ "key": "",
+ "out": "7a20540cc07bf72b582421fc342e82f52134b69841ec28ed189e2ea6a29dd2f82a640352d222b52f2911dc72a7dab31caadd80c6118f13c56b2a1e4373be0ea3"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8",
+ "key": "",
+ "out": "486f02c63e5467ea1fdde7e82bfacc2c1ba5d636d9f3d08b210da3f372f706ec218cc17ff60aef703bbe0c15c38ae55d286a684f864c78211ccab4178c92adba"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9",
+ "key": "",
+ "out": "1c7a5c1dedcd04a921788f7eb23361ca1953b04b9c7aec35d65ea3e4996db26f281278ea4ae666ad81027d98af57262cdbfa4c085f4210568c7e15eec7805114"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9ea",
+ "key": "",
+ "out": "9ce3fa9a860bdbd5378fd6d7b8b671c6cb7692910ce8f9b6cb4122cbcbe6ac06ca0422cef1225935053b7d193a81b9e972eb85a1d3074f14cbb5ec9f0573892d"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaeb",
+ "key": "",
+ "out": "a91187be5c371c4265c174fd4653b8ab708551f83d1fee1cc1479581bc006d6fb78fcc9a5dee1db3666f508f9780a37593ebcccf5fbed39667dc6361e921f779"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebec",
+ "key": "",
+ "out": "4625767d7b1d3d3ed2fbc674af14e0244152f2a4021fcf3311505d89bd81e2f9f9a500c3b199914db49500b3c98d03ea93286751a686a3b875daab0ccd63b44f"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebeced",
+ "key": "",
+ "out": "43dfdfe1b014fed3a2acabb7f3e9a182f2aa18019d27e3e6cdcf31a15b428e91e7b08cf5e5c376fce2d8a28ff85ab0a0a1656edb4a0a91532620096d9a5a652d"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedee",
+ "key": "",
+ "out": "279e3202be3989ba3112772585177487e4fe3ee3eab49c2f7fa7fe87cfe7b80d3e0355edff6d031e6c96c795db1c6f041880ec3824defacf9263820a8e7327de"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeef",
+ "key": "",
+ "out": "ea2d066ac229d4d4b616a8bedec734325224e4b4e58f1ae6dad7e40c2da29196c3b1ea9571dacc81e87328caa0211e09027b0524aa3f4a849917b3586747ebbb"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0",
+ "key": "",
+ "out": "49f014f5c61822c899ab5cae51be4044a4495e777deb7da9b6d8490efbb87530adf293daf079f94c33b7044ef62e2e5bb3eb11e17304f8453ee6ce24f033ddb0"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1",
+ "key": "",
+ "out": "9233490344e5b0dc5912671b7ae54cee7730dbe1f4c7d92a4d3e3aab50571708db51dcf9c2944591db651db32d22935b86944969be77d5b5feae6c3840a8db26"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2",
+ "key": "",
+ "out": "b6e75e6f4c7f453b7465d25b5ac8c7196902eaa953875228c8634e16e2ae1f38bc3275304335f5989eccc1e34167d4e68d7719968fba8e2fe67947c35c48e806"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3",
+ "key": "",
+ "out": "cc14ca665af1483efbc3af80080e650d5046a3932f4f51f3fe90a0705ec25104adf07839265dc51d43401411246e474f0d5e5637af94767283d53e0617e981f4"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4",
+ "key": "",
+ "out": "230a1c857cb2e7852e41b647e90e4585d2d881e1734dc38955356e8dd7bff39053092c6b38e236e1899525647073dddf6895d64206325e7647f275567b255909"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5",
+ "key": "",
+ "out": "cbb65321ac436e2ffdab2936359ce49023f7dee7614ef28d173c3d27c5d1bffa51553d433f8ee3c9e49c05a2b883cce954c9a8093b80612a0cdd4732e041f995"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6",
+ "key": "",
+ "out": "3e7e570074337275efb51315588034c3cf0dddca20b4612e0bd5b881e7e5476d319ce4fe9f19186e4c0826f44f131eb048e65be242b1172c63badb123ab0cbe8"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7",
+ "key": "",
+ "out": "d32e9ec02d38d4e1b8249df8dcb00c5b9c68eb8922672e3505393b6a210ba56f9496e5ee0490ef387c3cdec061f06bc0382d9304cafbb8e0cd33d57029e62df2"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8",
+ "key": "",
+ "out": "8c1512466089f05b3775c262b62d22b83854a83218130b4ec91b3ccbd293d2a54302cecaab9b100c68d1e6ddc8f07cddbdfe6fdaaaf099cc09d6b725879c6369"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9",
+ "key": "",
+ "out": "91a7f61c97c2911e4c812ef71d780ad8fa788794561d08303fd1c1cb608a46a12563086ec5b39d471aed94fb0f6c678a43b8792932f9028d772a22768ea23a9b"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fa",
+ "key": "",
+ "out": "4f6bb222a395e8b18f6ba155477aed3f0729ac9e83e16d31a2a8bc655422b837c891c6199e6f0d75799e3b691525c581953517f252c4b9e3a27a28fbaf49644c"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafb",
+ "key": "",
+ "out": "5d06c07e7a646c413a501c3f4bb2fc38127de7509b7077c4d9b5613201c1aa02fd5f79d2745915dd57fbcb4ce08695f6efc0cb3d2d330e19b4b0e6004ea6471e"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfc",
+ "key": "",
+ "out": "b96756e57909968f14b796a5d30f4c9d671472cf82c8cfb2caca7ac7a44ca0a14c9842d00c82e337502c94d5960aca4c492ea7b0df919ddf1aada2a275bb10d4"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfd",
+ "key": "",
+ "out": "ff0a015e98db9c99f03977710aac3e658c0d896f6d71d618ba79dc6cf72ac75b7c038eb6862dede4543e145413a6368d69f5722c827ba3ef25b6ae6440d39276"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfe",
+ "key": "",
+ "out": "5b21c5fd8868367612474fa2e70e9cfa2201ffeee8fafab5797ad58fefa17c9b5b107da4a3db6320baaf2c8617d5a51df914ae88da3867c2d41f0cc14fa67928"
+ },
+ {
+ "in": "",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "10ebb67700b1868efb4417987acf4690ae9d972fb7a590c2f02871799aaa4786b5e996e8f0f4eb981fc214b005f42d2ff4233499391653df7aefcbc13fc51568"
+ },
+ {
+ "in": "00",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "961f6dd1e4dd30f63901690c512e78e4b45e4742ed197c3c5e45c549fd25f2e4187b0bc9fe30492b16b0d0bc4ef9b0f34c7003fac09a5ef1532e69430234cebd"
+ },
+ {
+ "in": "0001",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "da2cfbe2d8409a0f38026113884f84b50156371ae304c4430173d08a99d9fb1b983164a3770706d537f49e0c916d9f32b95cc37a95b99d857436f0232c88a965"
+ },
+ {
+ "in": "000102",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "33d0825dddf7ada99b0e7e307104ad07ca9cfd9692214f1561356315e784f3e5a17e364ae9dbb14cb2036df932b77f4b292761365fb328de7afdc6d8998f5fc1"
+ },
+ {
+ "in": "00010203",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "beaa5a3d08f3807143cf621d95cd690514d0b49efff9c91d24b59241ec0eefa5f60196d407048bba8d2146828ebcb0488d8842fd56bb4f6df8e19c4b4daab8ac"
+ },
+ {
+ "in": "0001020304",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "098084b51fd13deae5f4320de94a688ee07baea2800486689a8636117b46c1f4c1f6af7f74ae7c857600456a58a3af251dc4723a64cc7c0a5ab6d9cac91c20bb"
+ },
+ {
+ "in": "000102030405",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "6044540d560853eb1c57df0077dd381094781cdb9073e5b1b3d3f6c7829e12066bbaca96d989a690de72ca3133a83652ba284a6d62942b271ffa2620c9e75b1f"
+ },
+ {
+ "in": "00010203040506",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "7a8cfe9b90f75f7ecb3acc053aaed6193112b6f6a4aeeb3f65d3de541942deb9e2228152a3c4bbbe72fc3b12629528cfbb09fe630f0474339f54abf453e2ed52"
+ },
+ {
+ "in": "0001020304050607",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "380beaf6ea7cc9365e270ef0e6f3a64fb902acae51dd5512f84259ad2c91f4bc4108db73192a5bbfb0cbcf71e46c3e21aee1c5e860dc96e8eb0b7b8426e6abe9"
+ },
+ {
+ "in": "000102030405060708",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "60fe3c4535e1b59d9a61ea8500bfac41a69dffb1ceadd9aca323e9a625b64da5763bad7226da02b9c8c4f1a5de140ac5a6c1124e4f718ce0b28ea47393aa6637"
+ },
+ {
+ "in": "00010203040506070809",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "4fe181f54ad63a2983feaaf77d1e7235c2beb17fa328b6d9505bda327df19fc37f02c4b6f0368ce23147313a8e5738b5fa2a95b29de1c7f8264eb77b69f585cd"
+ },
+ {
+ "in": "000102030405060708090a",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "f228773ce3f3a42b5f144d63237a72d99693adb8837d0e112a8a0f8ffff2c362857ac49c11ec740d1500749dac9b1f4548108bf3155794dcc9e4082849e2b85b"
+ },
+ {
+ "in": "000102030405060708090a0b",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "962452a8455cc56c8511317e3b1f3b2c37df75f588e94325fdd77070359cf63a9ae6e930936fdf8e1e08ffca440cfb72c28f06d89a2151d1c46cd5b268ef8563"
+ },
+ {
+ "in": "000102030405060708090a0b0c",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "43d44bfa18768c59896bf7ed1765cb2d14af8c260266039099b25a603e4ddc5039d6ef3a91847d1088d401c0c7e847781a8a590d33a3c6cb4df0fab1c2f22355"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "dcffa9d58c2a4ca2cdbb0c7aa4c4c1d45165190089f4e983bb1c2cab4aaeff1fa2b5ee516fecd780540240bf37e56c8bcca7fab980e1e61c9400d8a9a5b14ac6"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "6fbf31b45ab0c0b8dad1c0f5f4061379912dde5aa922099a030b725c73346c524291adef89d2f6fd8dfcda6d07dad811a9314536c2915ed45da34947e83de34e"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "a0c65bddde8adef57282b04b11e7bc8aab105b99231b750c021f4a735cb1bcfab87553bba3abb0c3e64a0b6955285185a0bd35fb8cfde557329bebb1f629ee93"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f10",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "f99d815550558e81eca2f96718aed10d86f3f1cfb675cce06b0eff02f617c5a42c5aa760270f2679da2677c5aeb94f1142277f21c7f79f3c4f0cce4ed8ee62b1"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f1011",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "95391da8fc7b917a2044b3d6f5374e1ca072b41454d572c7356c05fd4bc1e0f40b8bb8b4a9f6bce9be2c4623c399b0dca0dab05cb7281b71a21b0ebcd9e55670"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "04b9cd3d20d221c09ac86913d3dc63041989a9a1e694f1e639a3ba7e451840f750c2fc191d56ad61f2e7936bc0ac8e094b60caeed878c18799045402d61ceaf9"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f10111213",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "ec0e0ef707e4ed6c0c66f9e089e4954b058030d2dd86398fe84059631f9ee591d9d77375355149178c0cf8f8e7c49ed2a5e4f95488a2247067c208510fadc44c"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f1011121314",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "9a37cce273b79c09913677510eaf7688e89b3314d3532fd2764c39de022a2945b5710d13517af8ddc0316624e73bec1ce67df15228302036f330ab0cb4d218dd"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "4cf9bb8fb3d4de8b38b2f262d3c40f46dfe747e8fc0a414c193d9fcf753106ce47a18f172f12e8a2f1c26726545358e5ee28c9e2213a8787aafbc516d2343152"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f10111213141516",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "64e0c63af9c808fd893137129867fd91939d53f2af04be4fa268006100069b2d69daa5c5d8ed7fddcb2a70eeecdf2b105dd46a1e3b7311728f639ab489326bc9"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f1011121314151617",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "5e9c93158d659b2def06b0c3c7565045542662d6eee8a96a89b78ade09fe8b3dcc096d4fe48815d88d8f82620156602af541955e1f6ca30dce14e254c326b88f"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "7775dff889458dd11aef417276853e21335eb88e4dec9cfb4e9edb49820088551a2ca60339f12066101169f0dfe84b098fddb148d9da6b3d613df263889ad64b"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f10111213141516171819",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "f0d2805afbb91f743951351a6d024f9353a23c7ce1fc2b051b3a8b968c233f46f50f806ecb1568ffaa0b60661e334b21dde04f8fa155ac740eeb42e20b60d764"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "86a2af316e7d7754201b942e275364ac12ea8962ab5bd8d7fb276dc5fbffc8f9a28cae4e4867df6780d9b72524160927c855da5b6078e0b554aa91e31cb9ca1d"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "10bdf0caa0802705e706369baf8a3f79d72c0a03a80675a7bbb00be3a45e516424d1ee88efb56f6d5777545ae6e27765c3a8f5e493fc308915638933a1dfee55"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "b01781092b1748459e2e4ec178696627bf4ebafebba774ecf018b79a68aeb84917bf0b84bb79d17b743151144cd66b7b33a4b9e52c76c4e112050ff5385b7f0b"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "c6dbc61dec6eaeac81e3d5f755203c8e220551534a0b2fd105a91889945a638550204f44093dd998c076205dffad703a0e5cd3c7f438a7e634cd59fededb539e"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "eba51acffb4cea31db4b8d87e9bf7dd48fe97b0253ae67aa580f9ac4a9d941f2bea518ee286818cc9f633f2a3b9fb68e594b48cdd6d515bf1d52ba6c85a203a7"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "86221f3ada52037b72224f105d7999231c5e5534d03da9d9c0a12acb68460cd375daf8e24386286f9668f72326dbf99ba094392437d398e95bb8161d717f8991"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "5595e05c13a7ec4dc8f41fb70cb50a71bce17c024ff6de7af618d0cc4e9c32d9570d6d3ea45b86525491030c0d8f2b1836d5778c1ce735c17707df364d054347"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "ce0f4f6aca89590a37fe034dd74dd5fa65eb1cbd0a41508aaddc09351a3cea6d18cb2189c54b700c009f4cbf0521c7ea01be61c5ae09cb54f27bc1b44d658c82"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "7ee80b06a215a3bca970c77cda8761822bc103d44fa4b33f4d07dcb997e36d55298bceae12241b3fa07fa63be5576068da387b8d5859aeab701369848b176d42"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "940a84b6a84d109aab208c024c6ce9647676ba0aaa11f86dbb7018f9fd2220a6d901a9027f9abcf935372727cbf09ebd61a2a2eeb87653e8ecad1bab85dc8327"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "2020b78264a82d9f4151141adba8d44bf20c5ec062eee9b595a11f9e84901bf148f298e0c9f8777dcdbc7cc4670aac356cc2ad8ccb1629f16f6a76bcefbee760"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "d1b897b0e075ba68ab572adf9d9c436663e43eb3d8e62d92fc49c9be214e6f27873fe215a65170e6bea902408a25b49506f47babd07cecf7113ec10c5dd31252"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223242526",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "b14d0c62abfa469a357177e594c10c194243ed2025ab8aa5ad2fa41ad318e0ff48cd5e60bec07b13634a711d2326e488a985f31e31153399e73088efc86a5c55"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324252627",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "4169c5cc808d2697dc2a82430dc23e3cd356dc70a94566810502b8d655b39abf9e7f902fe717e0389219859e1945df1af6ada42e4ccda55a197b7100a30c30a1"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "258a4edb113d66c839c8b1c91f15f35ade609f11cd7f8681a4045b9fef7b0b24c82cda06a5f2067b368825e3914e53d6948ede92efd6e8387fa2e537239b5bee"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223242526272829",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "79d2d8696d30f30fb34657761171a11e6c3f1e64cbe7bebee159cb95bfaf812b4f411e2f26d9c421dc2c284a3342d823ec293849e42d1e46b0a4ac1e3c86abaa"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "8b9436010dc5dee992ae38aea97f2cd63b946d94fedd2ec9671dcde3bd4ce9564d555c66c15bb2b900df72edb6b891ebcadfeff63c9ea4036a998be7973981e7"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "c8f68e696ed28242bf997f5b3b34959508e42d613810f1e2a435c96ed2ff560c7022f361a9234b9837feee90bf47922ee0fd5f8ddf823718d86d1e16c6090071"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "b02d3eee4860d5868b2c39ce39bfe81011290564dd678c85e8783f29302dfc1399ba95b6b53cd9ebbf400cca1db0ab67e19a325f2d115812d25d00978ad1bca4"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "7693ea73af3ac4dad21ca0d8da85b3118a7d1c6024cfaf557699868217bc0c2f44a199bc6c0edd519798ba05bd5b1b4484346a47c2cadf6bf30b785cc88b2baf"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "a0e5c1c0031c02e48b7f09a5e896ee9aef2f17fc9e18e997d7f6cac7ae316422c2b1e77984e5f3a73cb45deed5d3f84600105e6ee38f2d090c7d0442ea34c46d"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "41daa6adcfdb69f1440c37b596440165c15ada596813e2e22f060fcd551f24dee8e04ba6890387886ceec4a7a0d7fc6b44506392ec3822c0d8c1acfc7d5aebe8"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "14d4d40d5984d84c5cf7523b7798b254e275a3a8cc0a1bd06ebc0bee726856acc3cbf516ff667cda2058ad5c3412254460a82c92187041363cc77a4dc215e487"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "d0e7a1e2b9a447fee83e2277e9ff8010c2f375ae12fa7aaa8ca5a6317868a26a367a0b69fbc1cf32a55d34eb370663016f3d2110230eba754028a56f54acf57c"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "e771aa8db5a3e043e8178f39a0857ba04a3f18e4aa05743cf8d222b0b095825350ba422f63382a23d92e4149074e816a36c1cd28284d146267940b31f8818ea2"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "feb4fd6f9e87a56bef398b3284d2bda5b5b0e166583a66b61e538457ff0584872c21a32962b9928ffab58de4af2edd4e15d8b35570523207ff4e2a5aa7754caa"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "462f17bf005fb1c1b9e671779f665209ec2873e3e411f98dabf240a1d5ec3f95ce6796b6fc23fe171903b502023467dec7273ff74879b92967a2a43a5a183d33"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "d3338193b64553dbd38d144bea71c5915bb110e2d88180dbc5db364fd6171df317fc7268831b5aef75e4342b2fad8797ba39eddcef80e6ec08159350b1ad696d"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233343536",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "e1590d585a3d39f7cb599abd479070966409a6846d4377acf4471d065d5db94129cc9be92573b05ed226be1e9b7cb0cabe87918589f80dadd4ef5ef25a93d28e"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "f8f3726ac5a26cc80132493a6fedcb0e60760c09cfc84cad178175986819665e76842d7b9fedf76dddebf5d3f56faaad4477587af21606d396ae570d8e719af2"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "30186055c07949948183c850e9a756cc09937e247d9d928e869e20bafc3cd9721719d34e04a0899b92c736084550186886efba2e790d8be6ebf040b209c439a4"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233343536373839",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "f3c4276cb863637712c241c444c5cc1e3554e0fddb174d035819dd83eb700b4ce88df3ab3841ba02085e1a99b4e17310c5341075c0458ba376c95a6818fbb3e2"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "0aa007c4dd9d5832393040a1583c930bca7dc5e77ea53add7e2b3f7c8e231368043520d4a3ef53c969b6bbfd025946f632bd7f765d53c21003b8f983f75e2a6a"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "08e9464720533b23a04ec24f7ae8c103145f765387d738777d3d343477fd1c58db052142cab754ea674378e18766c53542f71970171cc4f81694246b717d7564"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "d37ff7ad297993e7ec21e0f1b4b5ae719cdc83c5db687527f27516cbffa822888a6810ee5c1ca7bfe3321119be1ab7bfa0a502671c8329494df7ad6f522d440f"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "dd9042f6e464dcf86b1262f6accfafbd8cfd902ed3ed89abf78ffa482dbdeeb6969842394c9a1168ae3d481a017842f660002d42447c6b22f7b72f21aae021c9"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "bd965bf31e87d70327536f2a341cebc4768eca275fa05ef98f7f1b71a0351298de006fba73fe6733ed01d75801b4a928e54231b38e38c562b2e33ea1284992fa"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "65676d800617972fbd87e4b9514e1c67402b7a331096d3bfac22f1abb95374abc942f16e9ab0ead33b87c91968a6e509e119ff07787b3ef483e1dcdccf6e3022"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "939fa189699c5d2c81ddd1ffc1fa207c970b6a3685bb29ce1d3e99d42f2f7442da53e95a72907314f4588399a3ff5b0a92beb3f6be2694f9f86ecf2952d5b41c"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f4041",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "c516541701863f91005f314108ceece3c643e04fc8c42fd2ff556220e616aaa6a48aeb97a84bad74782e8dff96a1a2fa949339d722edcaa32b57067041df88cc"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "987fd6e0d6857c553eaebb3d34970a2c2f6e89a3548f492521722b80a1c21a153892346d2cba6444212d56da9a26e324dccbc0dcde85d4d2ee4399eec5a64e8f"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "ae56deb1c2328d9c4017706bce6e99d41349053ba9d336d677c4c27d9fd50ae6aee17e853154e1f4fe7672346da2eaa31eea53fcf24a22804f11d03da6abfc2b"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f4041424344",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "49d6a608c9bde4491870498572ac31aac3fa40938b38a7818f72383eb040ad39532bc06571e13d767e6945ab77c0bdc3b0284253343f9f6c1244ebf2ff0df866"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "da582ad8c5370b4469af862aa6467a2293b2b28bd80ae0e91f425ad3d47249fdf98825cc86f14028c3308c9804c78bfeeeee461444ce243687e1a50522456a1d"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243444546",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "d5266aa3331194aef852eed86d7b5b2633a0af1c735906f2e13279f14931a9fc3b0eac5ce9245273bd1aa92905abe16278ef7efd47694789a7283b77da3c70f8"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f4041424344454647",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "2962734c28252186a9a1111c732ad4de4506d4b4480916303eb7991d659ccda07a9911914bc75c418ab7a4541757ad054796e26797feaf36e9f6ad43f14b35a4"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "e8b79ec5d06e111bdfafd71e9f5760f00ac8ac5d8bf768f9ff6f08b8f026096b1cc3a4c973333019f1e3553e77da3f98cb9f542e0a90e5f8a940cc58e59844b3"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243444546474849",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "dfb320c44f9d41d1efdcc015f08dd5539e526e39c87d509ae6812a969e5431bf4fa7d91ffd03b981e0d544cf72d7b1c0374f8801482e6dea2ef903877eba675e"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "d88675118fdb55a5fb365ac2af1d217bf526ce1ee9c94b2f0090b2c58a06ca58187d7fe57c7bed9d26fca067b4110eefcd9a0a345de872abe20de368001b0745"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "b893f2fc41f7b0dd6e2f6aa2e0370c0cff7df09e3acfcc0e920b6e6fad0ef747c40668417d342b80d2351e8c175f20897a062e9765e6c67b539b6ba8b9170545"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "6c67ec5697accd235c59b486d7b70baeedcbd4aa64ebd4eef3c7eac189561a726250aec4d48cadcafbbe2ce3c16ce2d691a8cce06e8879556d4483ed7165c063"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "f1aa2b044f8f0c638a3f362e677b5d891d6fd2ab0765f6ee1e4987de057ead357883d9b405b9d609eea1b869d97fb16d9b51017c553f3b93c0a1e0f1296fedcd"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "cbaa259572d4aebfc1917acddc582b9f8dfaa928a198ca7acd0f2aa76a134a90252e6298a65b08186a350d5b7626699f8cb721a3ea5921b753ae3a2dce24ba3a"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "fa1549c9796cd4d303dcf452c1fbd5744fd9b9b47003d920b92de34839d07ef2a29ded68f6fc9e6c45e071a2e48bd50c5084e96b657dd0404045a1ddefe282ed"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "5cf2ac897ab444dcb5c8d87c495dbdb34e1838b6b629427caa51702ad0f9688525f13bec503a3c3a2c80a65e0b5715e8afab00ffa56ec455a49a1ad30aa24fcd"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f5051",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "9aaf80207bace17bb7ab145757d5696bde32406ef22b44292ef65d4519c3bb2ad41a59b62cc3e94b6fa96d32a7faadae28af7d35097219aa3fd8cda31e40c275"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "af88b163402c86745cb650c2988fb95211b94b03ef290eed9662034241fd51cf398f8073e369354c43eae1052f9b63b08191caa138aa54fea889cc7024236897"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "48fa7d64e1ceee27b9864db5ada4b53d00c9bc7626555813d3cd6730ab3cc06ff342d727905e33171bde6e8476e77fb1720861e94b73a2c538d254746285f430"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f5051525354",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "0e6fd97a85e904f87bfe85bbeb34f69e1f18105cf4ed4f87aec36c6e8b5f68bd2a6f3dc8a9ecb2b61db4eedb6b2ea10bf9cb0251fb0f8b344abf7f366b6de5ab"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "06622da5787176287fdc8fed440bad187d830099c94e6d04c8e9c954cda70c8bb9e1fc4a6d0baa831b9b78ef6648681a4867a11da93ee36e5e6a37d87fc63f6f"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253545556",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "1da6772b58fabf9c61f68d412c82f182c0236d7d575ef0b58dd22458d643cd1dfc93b03871c316d8430d312995d4197f0874c99172ba004a01ee295abac24e46"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f5051525354555657",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "3cd2d9320b7b1d5fb9aab951a76023fa667be14a9124e394513918a3f44096ae4904ba0ffc150b63bc7ab1eeb9a6e257e5c8f000a70394a5afd842715de15f29"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "04cdc14f7434e0b4be70cb41db4c779a88eaef6accebcb41f2d42fffe7f32a8e281b5c103a27021d0d08362250753cdf70292195a53a48728ceb5844c2d98bab"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253545556575859",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "9071b7a8a075d0095b8fb3ae5113785735ab98e2b52faf91d5b89e44aac5b5d4ebbf91223b0ff4c71905da55342e64655d6ef8c89a4768c3f93a6dc0366b5bc8"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "ebb30240dd96c7bc8d0abe49aa4edcbb4afdc51ff9aaf720d3f9e7fbb0f9c6d6571350501769fc4ebd0b2141247ff400d4fd4be414edf37757bb90a32ac5c65a"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "8532c58bf3c8015d9d1cbe00eef1f5082f8f3632fbe9f1ed4f9dfb1fa79e8283066d77c44c4af943d76b300364aecbd0648c8a8939bd204123f4b56260422dec"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "fe9846d64f7c7708696f840e2d76cb4408b6595c2f81ec6a28a7f2f20cb88cfe6ac0b9e9b8244f08bd7095c350c1d0842f64fb01bb7f532dfcd47371b0aeeb79"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "28f17ea6fb6c42092dc264257e29746321fb5bdaea9873c2a7fa9d8f53818e899e161bc77dfe8090afd82bf2266c5c1bc930a8d1547624439e662ef695f26f24"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "ec6b7d7f030d4850acae3cb615c21dd25206d63e84d1db8d957370737ba0e98467ea0ce274c66199901eaec18a08525715f53bfdb0aacb613d342ebdceeddc3b"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "b403d3691c03b0d3418df327d5860d34bbfcc4519bfbce36bf33b208385fadb9186bc78a76c489d89fd57e7dc75412d23bcd1dae8470ce9274754bb8585b13c5"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "31fc79738b8772b3f55cd8178813b3b52d0db5a419d30ba9495c4b9da0219fac6df8e7c23a811551a62b827f256ecdb8124ac8a6792ccfecc3b3012722e94463"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f6061",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "bb2039ec287091bcc9642fc90049e73732e02e577e2862b32216ae9bedcd730c4c284ef3968c368b7d37584f97bd4b4dc6ef6127acfe2e6ae2509124e66c8af4"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "f53d68d13f45edfcb9bd415e2831e938350d5380d3432278fc1c0c381fcb7c65c82dafe051d8c8b0d44e0974a0e59ec7bf7ed0459f86e96f329fc79752510fd3"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60616263",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "8d568c7984f0ecdf7640fbc483b5d8c9f86634f6f43291841b309a350ab9c1137d24066b09da9944bac54d5bb6580d836047aac74ab724b887ebf93d4b32eca9"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f6061626364",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "c0b65ce5a96ff774c456cac3b5f2c4cd359b4ff53ef93a3da0778be4900d1e8da1601e769e8f1b02d2a2f8c5b9fa10b44f1c186985468feeb008730283a6657d"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "4900bba6f5fb103ece8ec96ada13a5c3c85488e05551da6b6b33d988e611ec0fe2e3c2aa48ea6ae8986a3a231b223c5d27cec2eadde91ce07981ee652862d1e4"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60616263646566",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "c7f5c37c7285f927f76443414d4357ff789647d7a005a5a787e03c346b57f49f21b64fa9cf4b7e45573e23049017567121a9c3d4b2b73ec5e9413577525db45a"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f6061626364656667",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "ec7096330736fdb2d64b5653e7475da746c23a4613a82687a28062d3236364284ac01720ffb406cfe265c0df626a188c9e5963ace5d3d5bb363e32c38c2190a6"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "82e744c75f4649ec52b80771a77d475a3bc091989556960e276a5f9ead92a03f718742cdcfeaee5cb85c44af198adc43a4a428f5f0c2ddb0be36059f06d7df73"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60616263646566676869",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "2834b7a7170f1f5b68559ab78c1050ec21c919740b784a9072f6e5d69f828d70c919c5039fb148e39e2c8a52118378b064ca8d5001cd10a5478387b966715ed6"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "16b4ada883f72f853bb7ef253efcab0c3e2161687ad61543a0d2824f91c1f81347d86be709b16996e17f2dd486927b0288ad38d13063c4a9672c39397d3789b6"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "78d048f3a69d8b54ae0ed63a573ae350d89f7c6cf1f3688930de899afa037697629b314e5cd303aa62feea72a25bf42b304b6c6bcb27fae21c16d925e1fbdac3"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "0f746a48749287ada77a82961f05a4da4abdb7d77b1220f836d09ec814359c0ec0239b8c7b9ff9e02f569d1b301ef67c4612d1de4f730f81c12c40cc063c5caa"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "f0fc859d3bd195fbdc2d591e4cdac15179ec0f1dc821c11df1f0c1d26e6260aaa65b79fafacafd7d3ad61e600f250905f5878c87452897647a35b995bcadc3a3"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "2620f687e8625f6a412460b42e2cef67634208ce10a0cbd4dff7044a41b7880077e9f8dc3b8d1216d3376a21e015b58fb279b521d83f9388c7382c8505590b9b"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "227e3aed8d2cb10b918fcb04f9de3e6d0a57e08476d93759cd7b2ed54a1cbf0239c528fb04bbf288253e601d3bc38b21794afef90b17094a182cac557745e75f"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f70",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "1a929901b09c25f27d6b35be7b2f1c4745131fdebca7f3e2451926720434e0db6e74fd693ad29b777dc3355c592a361c4873b01133a57c2e3b7075cbdb86f4fc"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f7071",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "5fd7968bc2fe34f220b5e3dc5af9571742d73b7d60819f2888b629072b96a9d8ab2d91b82d0a9aaba61bbd39958132fcc4257023d1eca591b3054e2dc81c8200"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "dfcce8cf32870cc6a503eadafc87fd6f78918b9b4d0737db6810be996b5497e7e5cc80e312f61e71ff3e9624436073156403f735f56b0b01845c18f6caf772e6"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f70717273",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "02f7ef3a9ce0fff960f67032b296efca3061f4934d690749f2d01c35c81c14f39a67fa350bc8a0359bf1724bffc3bca6d7c7bba4791fd522a3ad353c02ec5aa8"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f7071727374",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "64be5c6aba65d594844ae78bb022e5bebe127fd6b6ffa5a13703855ab63b624dcd1a363f99203f632ec386f3ea767fc992e8ed9686586aa27555a8599d5b808f"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "f78585505c4eaa54a8b5be70a61e735e0ff97af944ddb3001e35d86c4e2199d976104b6ae31750a36a726ed285064f5981b503889fef822fcdc2898dddb7889a"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f70717273747576",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "e4b5566033869572edfd87479a5bb73c80e8759b91232879d96b1dda36c012076ee5a2ed7ae2de63ef8406a06aea82c188031b560beafb583fb3de9e57952a7e"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f7071727374757677",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "e1b3e7ed867f6c9484a2a97f7715f25e25294e992e41f6a7c161ffc2adc6daaeb7113102d5e6090287fe6ad94ce5d6b739c6ca240b05c76fb73f25dd024bf935"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "85fd085fdc12a080983df07bd7012b0d402a0f4043fcb2775adf0bad174f9b08d1676e476985785c0a5dcc41dbff6d95ef4d66a3fbdc4a74b82ba52da0512b74"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f70717273747576777879",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "aed8fa764b0fbff821e05233d2f7b0900ec44d826f95e93c343c1bc3ba5a24374b1d616e7e7aba453a0ada5e4fab5382409e0d42ce9c2bc7fb39a99c340c20f0"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "7ba3b2e297233522eeb343bd3ebcfd835a04007735e87f0ca300cbee6d416565162171581e4020ff4cf176450f1291ea2285cb9ebffe4c56660627685145051c"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "de748bcf89ec88084721e16b85f30adb1a6134d664b5843569babc5bbd1a15ca9b61803c901a4fef32965a1749c9f3a4e243e173939dc5a8dc495c671ab52145"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "aaf4d2bdf200a919706d9842dce16c98140d34bc433df320aba9bd429e549aa7a3397652a4d768277786cf993cde2338673ed2e6b66c961fefb82cd20c93338f"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "c408218968b788bf864f0997e6bc4c3dba68b276e2125a4843296052ff93bf5767b8cdce7131f0876430c1165fec6c4f47adaa4fd8bcfacef463b5d3d0fa61a0"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "76d2d819c92bce55fa8e092ab1bf9b9eab237a25267986cacf2b8ee14d214d730dc9a5aa2d7b596e86a1fd8fa0804c77402d2fcd45083688b218b1cdfa0dcbcb"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "72065ee4dd91c2d8509fa1fc28a37c7fc9fa7d5b3f8ad3d0d7a25626b57b1b44788d4caf806290425f9890a3a2a35a905ab4b37acfd0da6e4517b2525c9651e4"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "64475dfe7600d7171bea0b394e27c9b00d8e74dd1e416a79473682ad3dfdbb706631558055cfc8a40e07bd015a4540dcdea15883cbbf31412df1de1cd4152b91"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f8081",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "12cd1674a4488a5d7c2b3160d2e2c4b58371bedad793418d6f19c6ee385d70b3e06739369d4df910edb0b0a54cbff43d54544cd37ab3a06cfa0a3ddac8b66c89"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "60756966479dedc6dd4bcff8ea7d1d4ce4d4af2e7b097e32e3763518441147cc12b3c0ee6d2ecabf1198cec92e86a3616fba4f4e872f5825330adbb4c1dee444"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80818283",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "a7803bcb71bc1d0f4383dde1e0612e04f872b715ad30815c2249cf34abb8b024915cb2fc9f4e7cc4c8cfd45be2d5a91eab0941c7d270e2da4ca4a9f7ac68663a"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f8081828384",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "b84ef6a7229a34a750d9a98ee2529871816b87fbe3bc45b45fa5ae82d5141540211165c3c5d7a7476ba5a4aa06d66476f0d9dc49a3f1ee72c3acabd498967414"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "fae4b6d8efc3f8c8e64d001dabec3a21f544e82714745251b2b4b393f2f43e0da3d403c64db95a2cb6e23ebb7b9e94cdd5ddac54f07c4a61bd3cb10aa6f93b49"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80818283848586",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "34f7286605a122369540141ded79b8957255da2d4155abbf5a8dbb89c8eb7ede8eeef1daa46dc29d751d045dc3b1d658bb64b80ff8589eddb3824b13da235a6b"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f8081828384858687",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "3b3b48434be27b9eababba43bf6b35f14b30f6a88dc2e750c358470d6b3aa3c18e47db4017fa55106d8252f016371a00f5f8b070b74ba5f23cffc5511c9f09f0"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "ba289ebd6562c48c3e10a8ad6ce02e73433d1e93d7c9279d4d60a7e879ee11f441a000f48ed9f7c4ed87a45136d7dccdca482109c78a51062b3ba4044ada2469"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80818283848586878889",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "022939e2386c5a37049856c850a2bb10a13dfea4212b4c732a8840a9ffa5faf54875c5448816b2785a007da8a8d2bc7d71a54e4e6571f10b600cbdb25d13ede3"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "e6fec19d89ce8717b1a087024670fe026f6c7cbda11caef959bb2d351bf856f8055d1c0ebdaaa9d1b17886fc2c562b5e99642fc064710c0d3488a02b5ed7f6fd"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "94c96f02a8f576aca32ba61c2b206f907285d9299b83ac175c209a8d43d53bfe683dd1d83e7549cb906c28f59ab7c46f8751366a28c39dd5fe2693c9019666c8"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "31a0cd215ebd2cb61de5b9edc91e6195e31c59a5648d5c9f737e125b2605708f2e325ab3381c8dce1a3e958886f1ecdc60318f882cfe20a24191352e617b0f21"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "91ab504a522dce78779f4c6c6ba2e6b6db5565c76d3e7e7c920caf7f757ef9db7c8fcf10e57f03379ea9bf75eb59895d96e149800b6aae01db778bb90afbc989"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "d85cabc6bd5b1a01a5afd8c6734740da9fd1c1acc6db29bfc8a2e5b668b028b6b3154bfb8703fa3180251d589ad38040ceb707c4bad1b5343cb426b61eaa49c1"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "d62efbec2ca9c1f8bd66ce8b3f6a898cb3f7566ba6568c618ad1feb2b65b76c3ce1dd20f7395372faf28427f61c9278049cf0140df434f5633048c86b81e0399"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f90",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "7c8fdc6175439e2c3db15bafa7fb06143a6a23bc90f449e79deef73c3d492a671715c193b6fea9f036050b946069856b897e08c00768f5ee5ddcf70b7cd6d0e0"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f9091",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "58602ee7468e6bc9df21bd51b23c005f72d6cb013f0a1b48cbec5eca299299f97f09f54a9a01483eaeb315a6478bad37ba47ca1347c7c8fc9e6695592c91d723"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "27f5b79ed256b050993d793496edf4807c1d85a7b0a67c9c4fa99860750b0ae66989670a8ffd7856d7ce411599e58c4d77b232a62bef64d15275be46a68235ff"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f90919293",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "3957a976b9f1887bf004a8dca942c92d2b37ea52600f25e0c9bc5707d0279c00c6e85a839b0d2d8eb59c51d94788ebe62474a791cadf52cccf20f5070b6573fc"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f9091929394",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "eaa2376d55380bf772ecca9cb0aa4668c95c707162fa86d518c8ce0ca9bf7362b9f2a0adc3ff59922df921b94567e81e452f6c1a07fc817cebe99604b3505d38"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "c1e2c78b6b2734e2480ec550434cb5d613111adcc21d475545c3b1b7e6ff12444476e5c055132e2229dc0f807044bb919b1a5662dd38a9ee65e243a3911aed1a"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f90919293949596",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "8ab48713389dd0fcf9f965d3ce66b1e559a1f8c58741d67683cd971354f452e62d0207a65e436c5d5d8f8ee71c6abfe50e669004c302b31a7ea8311d4a916051"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f9091929394959697",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "24ce0addaa4c65038bd1b1c0f1452a0b128777aabc94a29df2fd6c7e2f85f8ab9ac7eff516b0e0a825c84a24cfe492eaad0a6308e46dd42fe8333ab971bb30ca"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "5154f929ee03045b6b0c0004fa778edee1d139893267cc84825ad7b36c63de32798e4a166d24686561354f63b00709a1364b3c241de3febf0754045897467cd4"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f90919293949596979899",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "e74e907920fd87bd5ad636dd11085e50ee70459c443e1ce5809af2bc2eba39f9e6d7128e0e3712c316da06f4705d78a4838e28121d4344a2c79c5e0db307a677"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "bf91a22334bac20f3fd80663b3cd06c4e8802f30e6b59f90d3035cc9798a217ed5a31abbda7fa6842827bdf2a7a1c21f6fcfccbb54c6c52926f32da816269be1"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "d9d5c74be5121b0bd742f26bffb8c89f89171f3f934913492b0903c271bbe2b3395ef259669bef43b57f7fcc3027db01823f6baee66e4f9fead4d6726c741fce"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "50c8b8cf34cd879f80e2faab3230b0c0e1cc3e9dcadeb1b9d97ab923415dd9a1fe38addd5c11756c67990b256e95ad6d8f9fedce10bf1c90679cde0ecf1be347"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "0a386e7cd5dd9b77a035e09fe6fee2c8ce61b5383c87ea43205059c5e4cd4f4408319bb0a82360f6a58e6c9ce3f487c446063bf813bc6ba535e17fc1826cfc91"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "1f1459cb6b61cbac5f0efe8fc487538f42548987fcd56221cfa7beb22504769e792c45adfb1d6b3d60d7b749c8a75b0bdf14e8ea721b95dca538ca6e25711209"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "e58b3836b7d8fedbb50ca5725c6571e74c0785e97821dab8b6298c10e4c079d4a6cdf22f0fedb55032925c16748115f01a105e77e00cee3d07924dc0d8f90659"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "b929cc6505f020158672deda56d0db081a2ee34c00c1100029bdf8ea98034fa4bf3e8655ec697fe36f40553c5bb46801644a627d3342f4fc92b61f03290fb381"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "72d353994b49d3e03153929a1e4d4f188ee58ab9e72ee8e512f29bc773913819ce057ddd7002c0433ee0a16114e3d156dd2c4a7e80ee53378b8670f23e33ef56"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "c70ef9bfd775d408176737a0736d68517ce1aaad7e81a93c8c1ed967ea214f56c8a377b1763e676615b60f3988241eae6eab9685a5124929d28188f29eab06f7"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "c230f0802679cb33822ef8b3b21bf7a9a28942092901d7dac3760300831026cf354c9232df3e084d9903130c601f63c1f4a4a4b8106e468cd443bbe5a734f45f"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "6f43094cafb5ebf1f7a4937ec50f56a4c9da303cbb55ac1f27f1f1976cd96beda9464f0e7b9c54620b8a9fba983164b8be3578425a024f5fe199c36356b88972"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "3745273f4c38225db2337381871a0c6aafd3af9b018c88aa02025850a5dc3a42a1a3e03e56cbf1b0876d63a441f1d2856a39b8801eb5af325201c415d65e97fe"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "c50c44cca3ec3edaae779a7e179450ebdda2f97067c690aa6c5a4ac7c30139bb27c0df4db3220e63cb110d64f37ffe078db72653e2daacf93ae3f0a2d1a7eb2e"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "8aef263e385cbc61e19b28914243262af5afe8726af3ce39a79c27028cf3ecd3f8d2dfd9cfc9ad91b58f6f20778fd5f02894a3d91c7d57d1e4b866a7f364b6be"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "28696141de6e2d9bcb3235578a66166c1448d3e905a1b482d423be4bc5369bc8c74dae0acc9cc123e1d8ddce9f97917e8c019c552da32d39d2219b9abf0fa8c8"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "2fb9eb2085830181903a9dafe3db428ee15be7662224efd643371fb25646aee716e531eca69b2bdc8233f1a8081fa43da1500302975a77f42fa592136710e9dc"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aa",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "66f9a7143f7a3314a669bf2e24bbb35014261d639f495b6c9c1f104fe8e320aca60d4550d69d52edbd5a3cdeb4014ae65b1d87aa770b69ae5c15f4330b0b0ad8"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaab",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "f4c4dd1d594c3565e3e25ca43dad82f62abea4835ed4cd811bcd975e46279828d44d4c62c3679f1b7f7b9dd4571d7b49557347b8c5460cbdc1bef690fb2a08c0"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabac",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "8f1dc9649c3a84551f8f6e91cac68242a43b1f8f328ee92280257387fa7559aa6db12e4aeadc2d26099178749c6864b357f3f83b2fb3efa8d2a8db056bed6bcc"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacad",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "3139c1a7f97afd1675d460ebbc07f2728aa150df849624511ee04b743ba0a833092f18c12dc91b4dd243f333402f59fe28abdbbbae301e7b659c7a26d5c0f979"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadae",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "06f94a2996158a819fe34c40de3cf0379fd9fb85b3e363ba3926a0e7d960e3f4c2e0c70c7ce0ccb2a64fc29869f6e7ab12bd4d3f14fce943279027e785fb5c29"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "c29c399ef3eee8961e87565c1ce263925fc3d0ce267d13e48dd9e732ee67b0f69fad56401b0f10fcaac119201046cca28c5b14abdea3212ae65562f7f138db3d"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "4cec4c9df52eef05c3f6faaa9791bc7445937183224ecc37a1e58d0132d35617531d7e795f52af7b1eb9d147de1292d345fe341823f8e6bc1e5badca5c656108"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "898bfbae93b3e18d00697eab7d9704fa36ec339d076131cefdf30edbe8d9cc81c3a80b129659b163a323bab9793d4feed92d54dae966c77529764a09be88db45"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "ee9bd0469d3aaf4f14035be48a2c3b84d9b4b1fff1d945e1f1c1d38980a951be197b25fe22c731f20aeacc930ba9c4a1f4762227617ad350fdabb4e80273a0f4"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "3d4d3113300581cd96acbf091c3d0f3c310138cd6979e6026cde623e2dd1b24d4a8638bed1073344783ad0649cc6305ccec04beb49f31c633088a99b65130267"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "95c0591ad91f921ac7be6d9ce37e0663ed8011c1cfd6d0162a5572e94368bac02024485e6a39854aa46fe38e97d6c6b1947cd272d86b06bb5b2f78b9b68d559d"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "227b79ded368153bf46c0a3ca978bfdbef31f3024a5665842468490b0ff748ae04e7832ed4c9f49de9b1706709d623e5c8c15e3caecae8d5e433430ff72f20eb"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "5d34f3952f0105eef88ae8b64c6ce95ebfade0e02c69b08762a8712d2e4911ad3f941fc4034dc9b2e479fdbcd279b902faf5d838bb2e0c6495d372b5b7029813"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "7f939bf8353abce49e77f14f3750af20b7b03902e1a1e7fb6aaf76d0259cd401a83190f15640e74f3e6c5a90e839c7821f6474757f75c7bf9002084ddc7a62dc"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "062b61a2f9a33a71d7d0a06119644c70b0716a504de7e5e1be49bd7b86e7ed6817714f9f0fc313d06129597e9a2235ec8521de36f7290a90ccfc1ffa6d0aee29"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "f29e01eeae64311eb7f1c6422f946bf7bea36379523e7b2bbaba7d1d34a22d5ea5f1c5a09d5ce1fe682cced9a4798d1a05b46cd72dff5c1b355440b2a2d476bc"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9ba",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "ec38cd3bbab3ef35d7cb6d5c914298351d8a9dc97fcee051a8a02f58e3ed6184d0b7810a5615411ab1b95209c3c810114fdeb22452084e77f3f847c6dbaafe16"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babb",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "c2aef5e0ca43e82641565b8cb943aa8ba53550caef793b6532fafad94b816082f0113a3ea2f63608ab40437ecc0f0229cb8fa224dcf1c478a67d9b64162b92d1"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbc",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "15f534efff7105cd1c254d074e27d5898b89313b7d366dc2d7d87113fa7d53aae13f6dba487ad8103d5e854c91fdb6e1e74b2ef6d1431769c30767dde067a35c"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbd",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "89acbca0b169897a0a2714c2df8c95b5b79cb69390142b7d6018bb3e3076b099b79a964152a9d912b1b86412b7e372e9cecad7f25d4cbab8a317be36492a67d7"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbe",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "e3c0739190ed849c9c962fd9dbb55e207e624fcac1eb417691515499eea8d8267b7e8f1287a63633af5011fde8c4ddf55bfdf722edf88831414f2cfaed59cb9a"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "8d6cf87c08380d2d1506eee46fd4222d21d8c04e585fbfd08269c98f702833a156326a0724656400ee09351d57b440175e2a5de93cc5f80db6daf83576cf75fa"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "da24bede383666d563eeed37f6319baf20d5c75d1635a6ba5ef4cfa1ac95487e96f8c08af600aab87c986ebad49fc70a58b4890b9c876e091016daf49e1d322e"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "f9d1d1b1e87ea7ae753a029750cc1cf3d0157d41805e245c5617bb934e732f0ae3180b78e05bfe76c7c3051e3e3ac78b9b50c05142657e1e03215d6ec7bfd0fc"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "11b7bc1668032048aa43343de476395e814bbbc223678db951a1b03a021efac948cfbe215f97fe9a72a2f6bc039e3956bfa417c1a9f10d6d7ba5d3d32ff323e5"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "b8d9000e4fc2b066edb91afee8e7eb0f24e3a201db8b6793c0608581e628ed0bcc4e5aa6787992a4bcc44e288093e63ee83abd0bc3ec6d0934a674a4da13838a"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "ce325e294f9b6719d6b61278276ae06a2564c03bb0b783fafe785bdf89c7d5acd83e78756d301b445699024eaeb77b54d477336ec2a4f332f2b3f88765ddb0c3"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "29acc30e9603ae2fccf90bf97e6cc463ebe28c1b2f9b4b765e70537c25c702a29dcbfbf14c99c54345ba2b51f17b77b5f15db92bbad8fa95c471f5d070a137cc"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "3379cbaae562a87b4c0425550ffdd6bfe1203f0d666cc7ea095be407a5dfe61ee91441cd5154b3e53b4f5fb31ad4c7a9ad5c7af4ae679aa51a54003a54ca6b2d"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "3095a349d245708c7cf550118703d7302c27b60af5d4e67fc978f8a4e60953c7a04f92fcf41aee64321ccb707a895851552b1e37b00bc5e6b72fa5bcef9e3fff"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "07262d738b09321f4dbccec4bb26f48cb0f0ed246ce0b31b9a6e7bc683049f1f3e5545f28ce932dd985c5ab0f43bd6de0770560af329065ed2e49d34624c2cbb"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "b6405eca8ee3316c87061cc6ec18dba53e6c250c63ba1f3bae9e55dd3498036af08cd272aa24d713c6020d77ab2f3919af1a32f307420618ab97e73953994fb4"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9ca",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "7ee682f63148ee45f6e5315da81e5c6e557c2c34641fc509c7a5701088c38a74756168e2cd8d351e88fd1a451f360a01f5b2580f9b5a2e8cfc138f3dd59a3ffc"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacb",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "1d263c179d6b268f6fa016f3a4f29e943891125ed8593c81256059f5a7b44af2dcb2030d175c00e62ecaf7ee96682aa07ab20a611024a28532b1c25b86657902"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcc",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "106d132cbdb4cd2597812846e2bc1bf732fec5f0a5f65dbb39ec4e6dc64ab2ce6d24630d0f15a805c3540025d84afa98e36703c3dbee713e72dde8465bc1be7e"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccd",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "0e79968226650667a8d862ea8da4891af56a4e3a8b6d1750e394f0dea76d640d85077bcec2cc86886e506751b4f6a5838f7f0b5fef765d9dc90dcdcbaf079f08"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdce",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "521156a82ab0c4e566e5844d5e31ad9aaf144bbd5a464fdca34dbd5717e8ff711d3ffebbfa085d67fe996a34f6d3e4e60b1396bf4b1610c263bdbb834d560816"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecf",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "1aba88befc55bc25efbce02db8b9933e46f57661baeabeb21cc2574d2a518a3cba5dc5a38e49713440b25f9c744e75f6b85c9d8f4681f676160f6105357b8406"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "5a9949fcb2c473cda968ac1b5d08566dc2d816d960f57e63b898fa701cf8ebd3f59b124d95bfbbedc5f1cf0e17d5eaed0c02c50b69d8a402cabcca4433b51fd4"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "b0cead09807c672af2eb2b0f06dde46cf5370e15a4096b1a7d7cbb36ec31c205fbefca00b7a4162fa89fb4fb3eb78d79770c23f44e7206664ce3cd931c291e5d"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "bb6664931ec97044e45b2ae420ae1c551a8874bc937d08e969399c3964ebdba8346cdd5d09caafe4c28ba7ec788191ceca65ddd6f95f18583e040d0f30d0364d"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "65bc770a5faa3792369803683e844b0be7ee96f29f6d6a35568006bd5590f9a4ef639b7a8061c7b0424b66b60ac34af3119905f33a9d8c3ae18382ca9b689900"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "ea9b4dca333336aaf839a45c6eaa48b8cb4c7ddabffea4f643d6357ea6628a480a5b45f2b052c1b07d1fedca918b6f1139d80f74c24510dcbaa4be70eacc1b06"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "e6342fb4a780ad975d0e24bce149989b91d360557e87994f6b457b895575cc02d0c15bad3ce7577f4c63927ff13f3e381ff7e72bdbe745324844a9d27e3f1c01"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "3e209c9b33e8e461178ab46b1c64b49a07fb745f1c8bc95fbfb94c6b87c69516651b264ef980937fad41238b91ddc011a5dd777c7efd4494b4b6ecd3a9c22ac0"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "fd6a3d5b1875d80486d6e69694a56dbb04a99a4d051f15db2689776ba1c4882e6d462a603b7015dc9f4b7450f05394303b8652cfb404a266962c41bae6e18a94"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "951e27517e6bad9e4195fc8671dee3e7e9be69cee1422cb9fecfce0dba875f7b310b93ee3a3d558f941f635f668ff832d2c1d033c5e2f0997e4c66f147344e02"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "8eba2f874f1ae84041903c7c4253c82292530fc8509550bfdc34c95c7e2889d5650b0ad8cb988e5c4894cb87fbfbb19612ea93ccc4c5cad17158b9763464b492"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9da",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "16f712eaa1b7c6354719a8e7dbdfaf55e4063a4d277d947550019b38dfb564830911057d50506136e2394c3b28945cc964967d54e3000c2181626cfb9b73efd2"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadb",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "c39639e7d5c7fb8cdd0fd3e6a52096039437122f21c78f1679cea9d78a734c56ecbeb28654b4f18e342c331f6f7229ec4b4bc281b2d80a6eb50043f31796c88c"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdc",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "72d081af99f8a173dcc9a0ac4eb3557405639a29084b54a40172912a2f8a395129d5536f0918e902f9e8fa6000995f4168ddc5f893011be6a0dbc9b8a1a3f5bb"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdd",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "c11aa81e5efd24d5fc27ee586cfd8847fbb0e27601ccece5ecca0198e3c7765393bb74457c7e7a27eb9170350e1fb53857177506be3e762cc0f14d8c3afe9077"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcddde",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "c28f2150b452e6c0c424bcde6f8d72007f9310fed7f2f87de0dbb64f4479d6c1441ba66f44b2accee61609177ed340128b407ecec7c64bbe50d63d22d8627727"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "f63d88122877ec30b8c8b00d22e89000a966426112bd44166e2f525b769ccbe9b286d437a0129130dde1a86c43e04bedb594e671d98283afe64ce331de9828fd"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "348b0532880b88a6614a8d7408c3f913357fbb60e995c60205be9139e74998aede7f4581e42f6b52698f7fa1219708c14498067fd1e09502de83a77dd281150c"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "5133dc8bef725359dff59792d85eaf75b7e1dcd1978b01c35b1b85fcebc63388ad99a17b6346a217dc1a9622ebd122ecf6913c4d31a6b52a695b86af00d741a0"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "2753c4c0e98ecad806e88780ec27fccd0f5c1ab547f9e4bf1659d192c23aa2cc971b58b6802580baef8adc3b776ef7086b2545c2987f348ee3719cdef258c403"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "b1663573ce4b9d8caefc865012f3e39714b9898a5da6ce17c25a6a47931a9ddb9bbe98adaa553beed436e89578455416c2a52a525cf2862b8d1d49a2531b7391"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "64f58bd6bfc856f5e873b2a2956ea0eda0d6db0da39c8c7fc67c9f9feefcff3072cdf9e6ea37f69a44f0c61aa0da3693c2db5b54960c0281a088151db42b11e8"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "0764c7be28125d9065c4b98a69d60aede703547c66a12e17e1c618994132f5ef82482c1e3fe3146cc65376cc109f0138ed9a80e49f1f3c7d610d2f2432f20605"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "f748784398a2ff03ebeb07e155e66116a839741a336e32da71ec696001f0ad1b25cd48c69cfca7265eca1dd71904a0ce748ac4124f3571076dfa7116a9cf00e9"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "3f0dbc0186bceb6b785ba78d2a2a013c910be157bdaffae81bb6663b1a73722f7f1228795f3ecada87cf6ef0078474af73f31eca0cc200ed975b6893f761cb6d"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "d4762cd4599876ca75b2b8fe249944dbd27ace741fdab93616cbc6e425460feb51d4e7adcc38180e7fc47c89024a7f56191adb878dfde4ead62223f5a2610efe"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "cd36b3d5b4c91b90fcbba79513cfee1907d8645a162afd0cd4cf4192d4a5f4c892183a8eacdb2b6b6a9d9aa8c11ac1b261b380dbee24ca468f1bfd043c58eefe"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9ea",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "98593452281661a53c48a9d8cd790826c1a1ce567738053d0bee4a91a3d5bd92eefdbabebe3204f2031ca5f781bda99ef5d8ae56e5b04a9e1ecd21b0eb05d3e1"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaeb",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "771f57dd2775ccdab55921d3e8e30ccf484d61fe1c1b9c2ae819d0fb2a12fab9be70c4a7a138da84e8280435daade5bbe66af0836a154f817fb17f3397e725a3"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebec",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "c60897c6f828e21f16fbb5f15b323f87b6c8955eabf1d38061f707f608abdd993fac3070633e286cf8339ce295dd352df4b4b40b2f29da1dd50b3a05d079e6bb"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebeced",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "8210cd2c2d3b135c2cf07fa0d1433cd771f325d075c6469d9c7f1ba0943cd4ab09808cabf4acb9ce5bb88b498929b4b847f681ad2c490d042db2aec94214b06b"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedee",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "1d4edfffd8fd80f7e4107840fa3aa31e32598491e4af7013c197a65b7f36dd3ac4b478456111cd4309d9243510782fa31b7c4c95fa951520d020eb7e5c36e4ef"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeef",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "af8e6e91fab46ce4873e1a50a8ef448cc29121f7f74deef34a71ef89cc00d9274bc6c2454bbb3230d8b2ec94c62b1dec85f3593bfa30ea6f7a44d7c09465a253"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "29fd384ed4906f2d13aa9fe7af905990938bed807f1832454a372ab412eea1f5625a1fcc9ac8343b7c67c5aba6e0b1cc4644654913692c6b39eb9187ceacd3ec"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "a268c7885d9874a51c44dffed8ea53e94f78456e0b2ed99ff5a3924760813826d960a15edbedbb5de5226ba4b074e71b05c55b9756bb79e55c02754c2c7b6c8a"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "0cf8545488d56a86817cd7ecb10f7116b7ea530a45b6ea497b6c72c997e09e3d0da8698f46bb006fc977c2cd3d1177463ac9057fdd1662c85d0c126443c10473"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "b39614268fdd8781515e2cfebf89b4d5402bab10c226e6344e6b9ae000fb0d6c79cb2f3ec80e80eaeb1980d2f8698916bd2e9f747236655116649cd3ca23a837"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "74bef092fc6f1e5dba3663a3fb003b2a5ba257496536d99f62b9d73f8f9eb3ce9ff3eec709eb883655ec9eb896b9128f2afc89cf7d1ab58a72f4a3bf034d2b4a"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "3a988d38d75611f3ef38b8774980b33e573b6c57bee0469ba5eed9b44f29945e7347967fba2c162e1c3be7f310f2f75ee2381e7bfd6b3f0baea8d95dfb1dafb1"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "58aedfce6f67ddc85a28c992f1c0bd0969f041e66f1ee88020a125cbfcfebcd61709c9c4eba192c15e69f020d462486019fa8dea0cd7a42921a19d2fe546d43d"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "9347bd291473e6b4e368437b8e561e065f649a6d8ada479ad09b1999a8f26b91cf6120fd3bfe014e83f23acfa4c0ad7b3712b2c3c0733270663112ccd9285cd9"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "b32163e7c5dbb5f51fdc11d2eac875efbbcb7e7699090a7e7ff8a8d50795af5d74d9ff98543ef8cdf89ac13d0485278756e0ef00c817745661e1d59fe38e7537"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "1085d78307b1c4b008c57a2e7e5b234658a0a82e4ff1e4aaac72b312fda0fe27d233bc5b10e9cc17fdc7697b540c7d95eb215a19a1a0e20e1abfa126efd568c7"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fa",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "4e5c734c7dde011d83eac2b7347b373594f92d7091b9ca34cb9c6f39bdf5a8d2f134379e16d822f6522170ccf2ddd55c84b9e6c64fc927ac4cf8dfb2a17701f2"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafb",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "695d83bd990a1117b3d0ce06cc888027d12a054c2677fd82f0d4fbfc93575523e7991a5e35a3752e9b70ce62992e268a877744cdd435f5f130869c9a2074b338"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfc",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "a6213743568e3b3158b9184301f3690847554c68457cb40fc9a4b8cfd8d4a118c301a07737aeda0f929c68913c5f51c80394f53bff1c3e83b2e40ca97eba9e15"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfd",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "d444bfa2362a96df213d070e33fa841f51334e4e76866b8139e8af3bb3398be2dfaddcbc56b9146de9f68118dc5829e74b0c28d7711907b121f9161cb92b69a9"
+ },
+ {
+ "in": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfe",
+ "key": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "out": "142709d62e28fcccd0af97fad0f8465b971e82201dc51070faa0372aa43e92484be1c1e73ba10906d5d1853db6a4106e0a7bf9800d373d6dee2d46d62ef2a461"
+ }
+ ]
+})
+++ /dev/null
-// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-import './calculate-pow.test.mjs'
-import './create-wallet.test.mjs'
-import './derive-accounts.test.mjs'
-import './import-wallet.test.mjs'
-import './lock-unlock-wallet.mjs'
-import './manage-rolodex.mjs'
-import './refresh-accounts.test.mjs'
-import './sign-blocks.test.mjs'
-import './tools.test.mjs'
-
-console.log('%cTESTING COMPLETE', 'color:orange;font-weight:bold')
--- /dev/null
+// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+'use strict'
+
+import { assert, stats, suite, test } from './GLOBALS.mjs'
+import { NANO_TEST_VECTORS } from './VECTORS.js'
+import { Bip44Wallet, Blake2bWallet } from '../dist/main.min.js'
+
+await suite('Account performance', async () => {
+ const COUNT = 0x200
+
+ await test(`Time to create ${COUNT} BIP-44 accounts`, async () => {
+ const wallet = await Bip44Wallet.create(NANO_TEST_VECTORS.PASSWORD)
+ await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)
+ const start = performance.now()
+ const accounts = await wallet.accounts(0, COUNT - 1)
+ const end = performance.now()
+ console.log(`Total: ${end - start} ms`)
+ console.log(`Average: ${(end - start) / COUNT} ms`)
+ assert.equals(accounts.length, COUNT)
+ wallet.destroy()
+ })
+
+ await test(`Time to create ${COUNT} BLAKE2b accounts`, async () => {
+ const wallet = await Blake2bWallet.create(NANO_TEST_VECTORS.PASSWORD)
+ await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)
+ const start = performance.now()
+ const accounts = await wallet.accounts(0, COUNT - 1)
+ const end = performance.now()
+ console.log(`Total: ${end - start} ms`)
+ console.log(`Average: ${(end - start) / COUNT} ms`)
+ assert.equals(accounts.length, COUNT)
+ wallet.destroy()
+ })
+
+ await test(`Time to create 1 BIP-44 account ${COUNT} times`, async () => {
+ const times = []
+ const wallet = await Bip44Wallet.create(NANO_TEST_VECTORS.PASSWORD)
+ await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)
+ for (let i = 0; i < COUNT; i++) {
+ const start = performance.now()
+ await wallet.accounts(i)
+ const end = performance.now()
+ times.push(end - start)
+ }
+ wallet.destroy()
+ console.log(stats(times))
+ })
+
+ await test(`Average time to create 1 BLAKE2b account ${COUNT} times`, async () => {
+ const times = []
+ const wallet = await Blake2bWallet.create(NANO_TEST_VECTORS.PASSWORD)
+ await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)
+ for (let i = 0; i < COUNT; i++) {
+ const start = performance.now()
+ await wallet.accounts(i)
+ const end = performance.now()
+ times.push(end - start)
+ }
+ wallet.destroy()
+ console.log(stats(times))
+ })
+})
--- /dev/null
+// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+'use strict'
+
+import { assert, stats, suite, test } from './GLOBALS.mjs'
+import { NANO_TEST_VECTORS } from './VECTORS.js'
+import { SendBlock } from '../dist/main.min.js'
+
+await suite('Block performance', async () => {
+ const COUNT = 0x200
+
+ await test(`libnemo: Time to calculate proof-of-work for a send block ${COUNT} times`, { skip: true }, async () => {
+ const times = []
+ const block = new SendBlock(
+ NANO_TEST_VECTORS.SEND_BLOCK.account,
+ NANO_TEST_VECTORS.SEND_BLOCK.balance,
+ NANO_TEST_VECTORS.SEND_BLOCK.link,
+ '0',
+ NANO_TEST_VECTORS.SEND_BLOCK.representative,
+ NANO_TEST_VECTORS.SEND_BLOCK.previous
+ )
+ for (let i = 0; i < COUNT; i++) {
+ const start = performance.now()
+ await block.pow()
+ const end = performance.now()
+ times.push(end - start)
+ console.log(`${block.work} (${end - start} ms)`)
+ }
+ console.log(stats(times))
+ })
+})
// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
// SPDX-License-Identifier: GPL-3.0-or-later
-// import './wallet.perf.js'
-// import './account.perf.js'
-import './block.perf.js'
+import './perf.wallet.js'
+import './perf.account.js'
+import './perf.block.js'
console.log('%cTESTING COMPLETE', 'color:orange;font-weight:bold')
'use strict'
-import { assert, average, skip, suite, test } from '#GLOBALS.mjs'
-import { NANO_TEST_VECTORS } from '#test/TEST_VECTORS.js'
-import { Bip44Wallet, Blake2bWallet } from '#dist/main.js'
+import { assert, stats, suite, test } from './GLOBALS.mjs'
+import { NANO_TEST_VECTORS } from './VECTORS.js'
+import { Bip44Wallet, Blake2bWallet } from '../dist/main.min.js'
await suite(`Wallet performance`, async () => {
const COUNT = 0x20
const wallet = await Bip44Wallet.create(NANO_TEST_VECTORS.PASSWORD)
const end = performance.now()
times.push(end - start)
+ wallet.destroy()
}
- const { total, arithmetic, harmonic, geometric } = average(times)
- console.log(`Total: ${total} ms`)
- console.log(`Average: ${arithmetic} ms`)
- console.log(`Harmonic: ${harmonic} ms`)
- console.log(`Geometric: ${geometric} ms`)
+ console.log(stats(times))
})
await test(`Time to create ${COUNT} BLAKE2b wallets`, async () => {
const wallet = await Blake2bWallet.create(NANO_TEST_VECTORS.PASSWORD)
const end = performance.now()
times.push(end - start)
+ wallet.destroy()
}
- const { total, arithmetic, harmonic, geometric } = average(times)
- console.log(`Total: ${total} ms`)
- console.log(`Average: ${arithmetic} ms`)
- console.log(`Harmonic: ${harmonic} ms`)
- console.log(`Geometric: ${geometric} ms`)
+ console.log(stats(times))
})
})
--- /dev/null
+<!--
+SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
+SPDX-License-Identifier: GPL-3.0-or-later
+-->
+
+<!DOCTYPE html>
+
+<head>
+ <link rel="icon" href="data:,">
+ <script type="module" src="./perf.main.mjs"></script>
+ <style>body{background:black;}</style>
+</head>
+
+<body></body>
+
+</html>
--- /dev/null
+// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>\r
+// SPDX-License-Identifier: GPL-3.0-or-later\r
+\r
+'use strict'\r
+\r
+import { assert, suite, test } from './GLOBALS.mjs'\r
+import { BLAKE2B_TEST_VECTORS } from './VECTORS.js'\r
+import { Blake2b } from '../dist/main.min.js'\r
+\r
+await suite('BLAKE2b test vectors', async () => {\r
+\r
+ await test('check 512 reference test vectors', async () => {\r
+ for (let i = 0; i < BLAKE2B_TEST_VECTORS.REFERENCE.length; i++) {\r
+ const test = BLAKE2B_TEST_VECTORS.REFERENCE[i]\r
+ if (test.in.length % 2 === 1) test.in = `0${test.in}`\r
+ const input = Uint8Array.from(test.in\r
+ .split(/(.{2})/)\r
+ .filter(v => v.length > 0)\r
+ .map(v => parseInt(v, 16))\r
+ )\r
+ let key\r
+ if (test.key.length > 0) {\r
+ if (test.key.length % 2 === 1) {\r
+ test.key = `0${test.key}`\r
+ }\r
+ key = Uint8Array.from(test.key\r
+ .split(/(.{2})/)\r
+ .filter(v => v.length > 0)\r
+ .map(v => parseInt(v, 16))\r
+ )\r
+ }\r
+ try {\r
+ const output = new Blake2b(64, key).update(input).digest('hex')\r
+ assert.equals(output, test.out)\r
+ } catch (err) {\r
+ console.error(`blake2b reference test vector ${i} failed`, { cause: err })\r
+ }\r
+ }\r
+ })\r
+\r
+ await test('check 64 libsodium test vectors', async () => {\r
+ for (let i = 0; i < BLAKE2B_TEST_VECTORS.LIBSODIUM.length; i++) {\r
+ const test = BLAKE2B_TEST_VECTORS.LIBSODIUM[i]\r
+ if (test.in.length % 2 === 1) test.in = `0${test.in}`\r
+ const input = Uint8Array.from(test.in\r
+ .split(/(.{2})/)\r
+ .filter(v => v.length > 0)\r
+ .map(v => parseInt(v, 16))\r
+ )\r
+ let key\r
+ if (test.key.length > 0) {\r
+ if (test.key.length % 2 === 1) {\r
+ test.key = `0${test.key}`\r
+ }\r
+ key = Uint8Array.from(test.key\r
+ .split(/(.{2})/)\r
+ .filter(v => v.length > 0)\r
+ .map(v => parseInt(v, 16))\r
+ )\r
+ }\r
+ let salt\r
+ if (test.salt && test.salt.length > 0) {\r
+ if (test.salt.length % 2 === 1) {\r
+ test.salt = `0${test.salt}`\r
+ }\r
+ salt = Uint8Array.from(test.salt\r
+ .split(/(.{2})/)\r
+ .filter(v => v.length > 0)\r
+ .map(v => parseInt(v, 16))\r
+ )\r
+ }\r
+ let personal\r
+ if (test.personal && test.personal.length > 0) {\r
+ if (test.personal.length % 2 === 1) {\r
+ test.personal = `0${test.personal}`\r
+ }\r
+ personal = Uint8Array.from(test.personal\r
+ .split(/(.{2})/)\r
+ .filter(v => v.length > 0)\r
+ .map(v => parseInt(v, 16))\r
+ )\r
+ }\r
+ try {\r
+ const output = new Blake2b(test.outlen ?? 64, key, salt, personal).update(input).digest('hex')\r
+ assert.equals(output, test.out)\r
+ } catch (err) {\r
+ console.error(`blake2b libsodium test vector ${i} failed`, { cause: err })\r
+ }\r
+ }\r
+ })\r
+})\r
\r
'use strict'\r
\r
-import { assert, suite, test } from '#GLOBALS.mjs'\r
-import { NANO_TEST_VECTORS } from '#test/TEST_VECTORS.js'\r
-import { SendBlock, Blake2b } from '#dist/main.js'\r
+import { assert, suite, test } from './GLOBALS.mjs'\r
+import { NANO_TEST_VECTORS } from './VECTORS.js'\r
+import { SendBlock, Blake2b } from '../dist/main.min.js'\r
\r
await suite('Calculate proof-of-work', async () => {\r
\r
\r
'use strict'\r
\r
-import { assert, skip, suite, test } from '#GLOBALS.mjs'\r
-import { NANO_TEST_VECTORS } from '#test/TEST_VECTORS.js'\r
-import { Bip44Wallet, Blake2bWallet, LedgerWallet } from '#dist/main.js'\r
+import { assert, suite, test } from './GLOBALS.mjs'\r
+import { NANO_TEST_VECTORS } from './VECTORS.js'\r
+import { Bip44Wallet, Blake2bWallet, LedgerWallet } from '../dist/main.min.js'\r
\r
await suite('Create wallets', async () => {\r
+\r
await test('BIP-44 wallet with random entropy', async () => {\r
const wallet = await Bip44Wallet.create(NANO_TEST_VECTORS.PASSWORD)\r
await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)\r
assert.ok(/^(?:[a-z]{3,} ){11,23}[a-z]{3,}$/.test(wallet.mnemonic))\r
assert.ok('seed' in wallet)\r
assert.ok(/[A-Fa-f0-9]{32,64}/.test(wallet.seed))\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('BLAKE2b wallet with random entropy', async () => {\r
assert.ok(/^(?:[a-z]{3,} ){11,23}[a-z]{3,}$/.test(wallet.mnemonic))\r
assert.ok('seed' in wallet)\r
assert.ok(/[A-Fa-f0-9]{32,64}/.test(wallet.seed))\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('BIP-44 replace invalid salt with empty string', async () => {\r
- const invalidArgs = [null, true, false, 0, 1, 2, { "foo": "bar" }]\r
+ const invalidArgs = [null, true, false, 0, 1, 2, { foo: 'bar' }]\r
for (const arg of invalidArgs) {\r
//@ts-expect-error\r
- await assert.resolves(Bip44Wallet.create(NANO_TEST_VECTORS.PASSWORD, arg))\r
+ const wallet = Bip44Wallet.create(NANO_TEST_VECTORS.PASSWORD, arg)\r
+ await assert.resolves(wallet);\r
+ (await wallet).destroy()\r
}\r
})\r
\r
await test('fail when using new', async () => {\r
- //@ts-expect-error\r
assert.throws(() => new Bip44Wallet())\r
- //@ts-expect-error\r
assert.throws(() => new Blake2bWallet())\r
- //@ts-expect-error\r
assert.throws(() => new LedgerWallet())\r
})\r
\r
await test('fail without a password', async () => {\r
- //@ts-expect-error\r
await assert.rejects(Bip44Wallet.create())\r
- //@ts-expect-error\r
await assert.rejects(Blake2bWallet.create())\r
})\r
-})\r
\r
-await skip('connect to ledger', async () => {\r
- const wallet = await LedgerWallet.create()\r
- assert.ok(wallet)\r
+ await test('connect to ledger', { skip: true }, async () => {\r
+ const wallet = await LedgerWallet.create()\r
+ assert.ok(wallet)\r
+ wallet.destroy()\r
+ })\r
})\r
\r
'use strict'\r
\r
-import { assert, skip, suite, test } from '#GLOBALS.mjs'\r
-import { NANO_TEST_VECTORS } from '#test/TEST_VECTORS.js'\r
-import { Bip44Wallet, Blake2bWallet, LedgerWallet } from '#dist/main.js'\r
+import { assert, suite, test } from './GLOBALS.mjs'\r
+import { NANO_TEST_VECTORS } from './VECTORS.js'\r
+import { Bip44Wallet, Blake2bWallet, LedgerWallet } from '../dist/main.min.js'\r
\r
await suite('Account derivation', async () => {\r
await test('should derive the first account from the given BIP-44 seed', async () => {\r
const wallet = await Bip44Wallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BIP39_SEED)\r
await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)\r
+ const account = await wallet.account()\r
+\r
+ assert.equals(account.privateKey, NANO_TEST_VECTORS.PRIVATE_0)\r
+ assert.equals(account.publicKey, NANO_TEST_VECTORS.PUBLIC_0)\r
+ assert.equals(account.address, NANO_TEST_VECTORS.ADDRESS_0)\r
+ assert.equals(account.index, 0)\r
+\r
const accounts = await wallet.accounts()\r
+ assert.equals(account, accounts[0])\r
\r
- assert.equals(accounts.length, 1)\r
- assert.equals(accounts[0].privateKey, NANO_TEST_VECTORS.PRIVATE_0)\r
- assert.equals(accounts[0].publicKey, NANO_TEST_VECTORS.PUBLIC_0)\r
- assert.equals(accounts[0].address, NANO_TEST_VECTORS.ADDRESS_0)\r
+ wallet.destroy()\r
})\r
\r
await test('should derive low indexed accounts from the given BIP-44 seed', async () => {\r
const accounts = await wallet.accounts(1, 2)\r
\r
assert.equals(accounts.length, 2)\r
- assert.equals(accounts[0].privateKey, NANO_TEST_VECTORS.PRIVATE_1)\r
- assert.equals(accounts[0].publicKey, NANO_TEST_VECTORS.PUBLIC_1)\r
- assert.equals(accounts[0].address, NANO_TEST_VECTORS.ADDRESS_1)\r
- assert.equals(accounts[1].privateKey, NANO_TEST_VECTORS.PRIVATE_2)\r
- assert.equals(accounts[1].publicKey, NANO_TEST_VECTORS.PUBLIC_2)\r
- assert.equals(accounts[1].address, NANO_TEST_VECTORS.ADDRESS_2)\r
+ assert.equals(accounts[1].privateKey, NANO_TEST_VECTORS.PRIVATE_1)\r
+ assert.equals(accounts[1].publicKey, NANO_TEST_VECTORS.PUBLIC_1)\r
+ assert.equals(accounts[1].address, NANO_TEST_VECTORS.ADDRESS_1)\r
+ assert.equals(accounts[2].privateKey, NANO_TEST_VECTORS.PRIVATE_2)\r
+ assert.equals(accounts[2].publicKey, NANO_TEST_VECTORS.PUBLIC_2)\r
+ assert.equals(accounts[2].address, NANO_TEST_VECTORS.ADDRESS_2)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('should derive high indexed accounts from the given seed', async () => {\r
const accounts = await wallet.accounts(0x70000000, 0x700000ff)\r
\r
assert.equals(accounts.length, 0x100)\r
- for (let i = 0; i < accounts.length; i++) {\r
+ for (let i = 0x70000000; i < 0x700000ff; i++) {\r
const a = accounts[i]\r
assert.exists(a)\r
assert.exists(a.address)\r
assert.exists(a.publicKey)\r
assert.exists(a.privateKey)\r
assert.exists(a.index)\r
- assert.equals(a.index, i + 0x70000000)\r
+ assert.equals(a.index, i)\r
}\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('should derive accounts for a BLAKE2b wallet', async () => {\r
assert.exists(a.privateKey)\r
assert.exists(a.index)\r
}\r
+\r
+ wallet.destroy()\r
})\r
\r
- await skip('fetch the first account from a Ledger device', async () => {\r
+ await test('fetch the first account from a Ledger device', { skip: true }, async () => {\r
const wallet = await LedgerWallet.create()\r
const accounts = await wallet.accounts()\r
\r
assert.equals(accounts.length, 1)\r
assert.exists(accounts[0].publicKey)\r
assert.exists(accounts[0].address)\r
+\r
+ wallet.destroy()\r
})\r
})\r
\r
'use strict'\r
\r
-import { assert, suite, test } from '#GLOBALS.mjs'\r
-import { BIP32_TEST_VECTORS, CUSTOM_TEST_VECTORS, NANO_TEST_VECTORS, TREZOR_TEST_VECTORS } from '#test/TEST_VECTORS.js'\r
-import { Account, Bip44Wallet, Blake2bWallet } from '#dist/main.js'\r
+import { assert, suite, test } from './GLOBALS.mjs'\r
+import { BIP32_TEST_VECTORS, CUSTOM_TEST_VECTORS, NANO_TEST_VECTORS, TREZOR_TEST_VECTORS } from './VECTORS.js'\r
+import { Account, Bip44Wallet, Blake2bWallet } from '../dist/main.min.js'\r
\r
await suite('Import wallets', async () => {\r
+\r
await test('nano.org BIP-44 test vector mnemonic', async () => {\r
const wallet = await Bip44Wallet.fromMnemonic(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.MNEMONIC, NANO_TEST_VECTORS.PASSWORD)\r
await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)\r
assert.equals(accounts[0].privateKey, NANO_TEST_VECTORS.PRIVATE_0)\r
assert.equals(accounts[0].publicKey, NANO_TEST_VECTORS.PUBLIC_0)\r
assert.equals(accounts[0].address, NANO_TEST_VECTORS.ADDRESS_0)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('nano.org BIP-44 test vector seed with no mnemonic', async () => {\r
assert.equals(accounts[0].privateKey, NANO_TEST_VECTORS.PRIVATE_0)\r
assert.equals(accounts[0].publicKey, NANO_TEST_VECTORS.PUBLIC_0)\r
assert.equals(accounts[0].address, NANO_TEST_VECTORS.ADDRESS_0)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('Trezor-derived BIP-44 entropy for 12-word mnemonic', async () => {\r
assert.equals(account.privateKey, CUSTOM_TEST_VECTORS.PRIVATE_0)\r
assert.equals(account.publicKey, CUSTOM_TEST_VECTORS.PUBLIC_0)\r
assert.equals(account.address, CUSTOM_TEST_VECTORS.ADDRESS_0)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('Trezor-derived BIP-44 entropy for 15-word mnemonic', async () => {\r
assert.equals(account.privateKey, CUSTOM_TEST_VECTORS.PRIVATE_1)\r
assert.equals(account.publicKey, CUSTOM_TEST_VECTORS.PUBLIC_1)\r
assert.equals(account.address, CUSTOM_TEST_VECTORS.ADDRESS_1)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('Trezor-derived BIP-44 entropy for 18-word mnemonic', async () => {\r
assert.equals(account.privateKey, CUSTOM_TEST_VECTORS.PRIVATE_2)\r
assert.equals(account.publicKey, CUSTOM_TEST_VECTORS.PUBLIC_2)\r
assert.equals(account.address, CUSTOM_TEST_VECTORS.ADDRESS_2)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('Trezor-derived BIP-44 entropy for 21-word mnemonic', async () => {\r
assert.equals(account.privateKey, CUSTOM_TEST_VECTORS.PRIVATE_3)\r
assert.equals(account.publicKey, CUSTOM_TEST_VECTORS.PUBLIC_3)\r
assert.equals(account.address, CUSTOM_TEST_VECTORS.ADDRESS_3)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('BIP-44 zero-string entropy', async () => {\r
assert.exists(accounts[i].privateKey)\r
assert.equals(accounts[i].index, i)\r
}\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('BLAKE2b zero-string seed', async () => {\r
assert.exists(accounts[i].privateKey)\r
assert.equals(accounts[i].index, i)\r
}\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('Trezor-derived BLAKE2b test vectors verified with third-party libraries', async () => {\r
assert.equals(accounts[1].privateKey, TREZOR_TEST_VECTORS.BLAKE2B_1_PRIVATE_1)\r
assert.equals(accounts[1].publicKey, TREZOR_TEST_VECTORS.BLAKE2B_1_PUBLIC_1)\r
assert.equals(accounts[1].address, TREZOR_TEST_VECTORS.BLAKE2B_1_ADDRESS_1)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('BLAKE2b seed creates identical wallet as its derived mnemonic', async () => {\r
assert.equals(imported.seed, wallet.seed)\r
assert.equals(importedAccount.privateKey, walletAccount.privateKey)\r
assert.equals(importedAccount.publicKey, walletAccount.publicKey)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('BLAKE2b mnemonic for maximum seed value', async () => {\r
assert.equals(accounts[0].privateKey, TREZOR_TEST_VECTORS.BLAKE2B_3_PRIVATE_0)\r
assert.equals(accounts[0].publicKey, TREZOR_TEST_VECTORS.BLAKE2B_3_PUBLIC_0)\r
assert.equals(accounts[0].address, TREZOR_TEST_VECTORS.BLAKE2B_3_ADDRESS_0)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('Reject invalid entropy', async () => {\r
})\r
\r
await suite('Retrieve wallets from session storage using a wallet-generated ID', async () => {\r
+\r
await test('Bip44Wallet', async () => {\r
const id = (await Bip44Wallet.fromMnemonic(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.MNEMONIC, NANO_TEST_VECTORS.PASSWORD)).id\r
const wallet = await Bip44Wallet.restore(id)\r
assert.ok('seed' in wallet)\r
assert.equals(wallet.mnemonic, NANO_TEST_VECTORS.MNEMONIC)\r
assert.equals(wallet.seed, NANO_TEST_VECTORS.BIP39_SEED)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('Blake2bWallet', async () => {\r
assert.ok('seed' in wallet)\r
assert.equals(wallet.mnemonic, TREZOR_TEST_VECTORS.MNEMONIC_0)\r
assert.equals(wallet.seed, TREZOR_TEST_VECTORS.ENTROPY_0)\r
+\r
+ wallet.destroy()\r
})\r
})\r
\r
'use strict'\r
\r
-import { assert, suite, test } from '#GLOBALS.mjs'\r
-import { NANO_TEST_VECTORS, TREZOR_TEST_VECTORS } from '#test/TEST_VECTORS.js'\r
-import { Bip44Wallet, Blake2bWallet } from '#dist/main.js'\r
+import { assert, suite, test } from './GLOBALS.mjs'\r
+import { NANO_TEST_VECTORS, TREZOR_TEST_VECTORS } from './VECTORS.js'\r
+import { Bip44Wallet, Blake2bWallet } from '../dist/main.min.js'\r
\r
await suite('Lock and unlock wallets', async () => {\r
+\r
await test('locking and unlocking a Bip44Wallet with a password', async () => {\r
const wallet = await Bip44Wallet.fromMnemonic(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.MNEMONIC, NANO_TEST_VECTORS.PASSWORD)\r
\r
assert.ok('seed' in wallet)\r
assert.equals(wallet.mnemonic, NANO_TEST_VECTORS.MNEMONIC)\r
assert.equals(wallet.seed, NANO_TEST_VECTORS.BIP39_SEED)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('locking and unlocking a Bip44Wallet with a random CryptoKey', async () => {\r
assert.ok('seed' in wallet)\r
assert.equals(wallet.mnemonic, NANO_TEST_VECTORS.MNEMONIC)\r
assert.equals(wallet.seed, NANO_TEST_VECTORS.BIP39_SEED)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('fail to unlock a Bip44Wallet with different passwords', async () => {\r
assert.ok('seed' in wallet)\r
assert.notEqual(wallet.mnemonic, NANO_TEST_VECTORS.MNEMONIC)\r
assert.notEqual(wallet.seed, NANO_TEST_VECTORS.BIP39_SEED)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('fail to unlock a Bip44Wallet with different keys', async () => {\r
assert.ok('seed' in wallet)\r
assert.notEqual(wallet.mnemonic, NANO_TEST_VECTORS.MNEMONIC)\r
assert.notEqual(wallet.seed, NANO_TEST_VECTORS.BIP39_SEED)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('fail to unlock a Bip44Wallet with different valid inputs', async () => {\r
assert.ok('seed' in wallet)\r
assert.notEqual(wallet.mnemonic, NANO_TEST_VECTORS.MNEMONIC)\r
assert.notEqual(wallet.seed, NANO_TEST_VECTORS.BIP39_SEED)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('fail to unlock a Bip44Wallet with no input', async () => {\r
const wallet = await Bip44Wallet.fromMnemonic(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.MNEMONIC, NANO_TEST_VECTORS.PASSWORD)\r
await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)\r
\r
- //@ts-expect-error\r
await assert.rejects(wallet.lock(), { message: 'Failed to lock wallet' })\r
assert.ok('mnemonic' in wallet)\r
assert.ok('seed' in wallet)\r
\r
await wallet.lock('password')\r
\r
- //@ts-expect-error\r
await assert.rejects(wallet.unlock(), { message: 'Failed to unlock wallet' })\r
assert.ok('mnemonic' in wallet)\r
assert.ok('seed' in wallet)\r
assert.notEqual(wallet.mnemonic, NANO_TEST_VECTORS.MNEMONIC)\r
assert.notEqual(wallet.seed, NANO_TEST_VECTORS.BIP39_SEED)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('fail to unlock a Bip44Wallet with invalid input', async () => {\r
const wallet = await Bip44Wallet.fromMnemonic(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.MNEMONIC, NANO_TEST_VECTORS.PASSWORD)\r
await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)\r
\r
- //@ts-expect-error\r
await assert.rejects(wallet.lock(1), { message: 'Failed to lock wallet' })\r
assert.ok('mnemonic' in wallet)\r
assert.ok('seed' in wallet)\r
\r
await wallet.lock(NANO_TEST_VECTORS.PASSWORD)\r
\r
- //@ts-expect-error\r
await assert.rejects(wallet.unlock(1), { message: 'Failed to unlock wallet' })\r
assert.ok('mnemonic' in wallet)\r
assert.ok('seed' in wallet)\r
assert.notEqual(wallet.mnemonic, NANO_TEST_VECTORS.MNEMONIC)\r
assert.notEqual(wallet.seed, NANO_TEST_VECTORS.BIP39_SEED)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('locking and unlocking a Blake2bWallet with a password', async () => {\r
assert.ok('seed' in wallet)\r
assert.equals(wallet.mnemonic, TREZOR_TEST_VECTORS.MNEMONIC_0)\r
assert.equals(wallet.seed, TREZOR_TEST_VECTORS.ENTROPY_0)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('locking and unlocking a Blake2bWallet with a random CryptoKey', async () => {\r
assert.ok('seed' in wallet)\r
assert.equals(wallet.mnemonic, TREZOR_TEST_VECTORS.MNEMONIC_1)\r
assert.equals(wallet.seed, TREZOR_TEST_VECTORS.ENTROPY_1)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('fail to unlock a Blake2bWallet with different passwords', async () => {\r
assert.ok('seed' in wallet)\r
assert.notEqual(wallet.mnemonic, TREZOR_TEST_VECTORS.MNEMONIC_1)\r
assert.notEqual(wallet.seed, TREZOR_TEST_VECTORS.ENTROPY_1)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('fail to unlock a Blake2bWallet with different keys', async () => {\r
assert.ok('seed' in wallet)\r
assert.notEqual(wallet.mnemonic, TREZOR_TEST_VECTORS.MNEMONIC_1)\r
assert.notEqual(wallet.seed, TREZOR_TEST_VECTORS.ENTROPY_1)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('fail to unlock a Blake2bWallet with different valid inputs', async () => {\r
assert.ok('seed' in wallet)\r
assert.notEqual(wallet.mnemonic, TREZOR_TEST_VECTORS.MNEMONIC_1)\r
assert.notEqual(wallet.seed, TREZOR_TEST_VECTORS.ENTROPY_1)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('fail to unlock a Blake2bWallet with no input', async () => {\r
const wallet = await Blake2bWallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, TREZOR_TEST_VECTORS.ENTROPY_1)\r
await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)\r
\r
- //@ts-expect-error\r
await assert.rejects(wallet.lock(), { message: 'Failed to lock wallet' })\r
assert.ok('mnemonic' in wallet)\r
assert.ok('seed' in wallet)\r
\r
await wallet.lock(NANO_TEST_VECTORS.PASSWORD)\r
\r
- //@ts-expect-error\r
await assert.rejects(wallet.unlock(), { message: 'Failed to unlock wallet' })\r
assert.ok('mnemonic' in wallet)\r
assert.ok('seed' in wallet)\r
assert.notEqual(wallet.mnemonic, TREZOR_TEST_VECTORS.MNEMONIC_1)\r
assert.notEqual(wallet.seed, TREZOR_TEST_VECTORS.ENTROPY_1)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('fail to unlock a Blake2bWallet with invalid input', async () => {\r
const wallet = await Blake2bWallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, TREZOR_TEST_VECTORS.ENTROPY_1)\r
await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)\r
\r
- //@ts-expect-error\r
await assert.rejects(wallet.lock(1), { message: 'Failed to lock wallet' })\r
assert.ok('mnemonic' in wallet)\r
assert.ok('seed' in wallet)\r
\r
await wallet.lock(NANO_TEST_VECTORS.PASSWORD)\r
\r
- //@ts-expect-error\r
await assert.rejects(wallet.unlock(1), { message: 'Failed to unlock wallet' })\r
assert.ok('mnemonic' in wallet)\r
assert.ok('seed' in wallet)\r
assert.notEqual(wallet.mnemonic, TREZOR_TEST_VECTORS.MNEMONIC_1)\r
assert.notEqual(wallet.seed, TREZOR_TEST_VECTORS.ENTROPY_1)\r
+\r
+ wallet.destroy()\r
})\r
})\r
--- /dev/null
+// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+import './test.blake2b.mjs'
+import './test.calculate-pow.mjs'
+import './test.create-wallet.mjs'
+import './test.derive-accounts.mjs'
+import './test.import-wallet.mjs'
+import './test.lock-unlock-wallet.mjs'
+import './test.manage-rolodex.mjs'
+import './test.refresh-accounts.mjs'
+import './test.sign-blocks.mjs'
+import './test.tools.mjs'
+
+console.log('%cTESTING COMPLETE', 'color:orange;font-weight:bold')
'use strict'
-import { assert, suite, test } from '#GLOBALS.mjs'
-import { NANO_TEST_VECTORS } from '#test/TEST_VECTORS.js'
-import { Rolodex, Tools } from '#dist/main.js'
+import { assert, suite, test } from './GLOBALS.mjs'
+import { NANO_TEST_VECTORS } from './VECTORS.js'
+import { Rolodex, Tools } from '../dist/main.min.js'
await suite('Rolodex valid contact management', async () => {
+
await test('should create a rolodex and add two contacts', async () => {
const rolodex = new Rolodex()
assert.equals(rolodex.constructor, Rolodex)
})
await suite('Rolodex exceptions', async () => {
+
await test('should throw if adding no data', async () => {
const rolodex = new Rolodex()
//@ts-expect-error
})
await suite('Rolodex data signature verification', async () => {
+
await test('should verify valid data and signature', async () => {
const data = 'Test data'
const signature = await Tools.sign(NANO_TEST_VECTORS.PRIVATE_0, data)
'use strict'
-import { assert, skip, suite, test } from '#GLOBALS.mjs'
-import { NANO_TEST_VECTORS } from '#test/TEST_VECTORS.js'
-import { Account, Bip44Wallet, Rpc } from '#dist/main.js'
+import { assert, suite, test } from './GLOBALS.mjs'
+import { NANO_TEST_VECTORS } from './VECTORS.js'
+import { Account, Bip44Wallet, Rpc } from '../dist/main.min.js'
let rpc
//@ts-ignore
rpc = new Rpc(process?.env?.NODE_URL ?? '', process?.env?.API_KEY_NAME)
}
-await skip('refreshing account info', async () => {
+await suite('refreshing account info', { skip: true }, async () => {
+
await test('fetch balance, frontier, and representative', async () => {
const wallet = await Bip44Wallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BIP39_SEED)
await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)
assert.notEqual(account.representative?.address, undefined)
assert.notEqual(account.representative?.address, null)
assert.notEqual(account.representative?.address, '')
+
+ wallet.destroy()
})
await test('throw when refreshing unopened account', async () => {
const account = accounts[0]
await assert.rejects(account.refresh(rpc),
{ message: 'Account not found' })
+
+ wallet.destroy()
})
await test('throw when referencing invalid account index', async () => {
const account = accounts[0]
await assert.rejects(account.refresh(invalidNode),
{ message: 'Account not found' })
+
+ wallet.destroy()
})
})
-await skip('Fetch next unopened account', async () => {
+await suite('Fetch next unopened account', { skip: true }, async () => {
+
await test('return correct account from test vector', async () => {
const wallet = await Bip44Wallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BIP39_SEED)
await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)
assert.ok(account)
assert.equals(account.address, NANO_TEST_VECTORS.ADDRESS_1)
assert.equals(account.publicKey, NANO_TEST_VECTORS.PUBLIC_1)
+
+ wallet.destroy()
})
await test('return successfully for small batch size', async () => {
assert.ok(account)
assert.equals(account.address, NANO_TEST_VECTORS.ADDRESS_1)
assert.equals(account.publicKey, NANO_TEST_VECTORS.PUBLIC_1)
+
+ wallet.destroy()
})
await test('return successfully for large batch size', async () => {
assert.ok(account)
assert.equals(account.address, NANO_TEST_VECTORS.ADDRESS_1)
assert.equals(account.publicKey, NANO_TEST_VECTORS.PUBLIC_1)
+
+ wallet.destroy()
})
await test('should throw on invalid node URL', async () => {
await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)
//@ts-expect-error
await assert.rejects(wallet.getNextNewAccount())
- //@ts-expect-error
await assert.rejects(wallet.getNextNewAccount(null))
- //@ts-expect-error
await assert.rejects(wallet.getNextNewAccount(1))
- //@ts-expect-error
await assert.rejects(wallet.getNextNewAccount(''))
- //@ts-expect-error
await assert.rejects(wallet.getNextNewAccount('foo'))
+
+ wallet.destroy()
})
await test('should throw on invalid batch size', async () => {
await assert.rejects(wallet.getNextNewAccount(rpc, 'foo'))
//@ts-expect-error
await assert.rejects(wallet.getNextNewAccount(rpc, { 'foo': 'bar' }))
+
+ wallet.destroy()
})
})
-await skip('Refreshing wallet accounts', async () => {
+await suite('Refreshing wallet accounts', { skip: true }, async () => {
+
await test('should get balance, frontier, and representative for one account', async () => {
const wallet = await Bip44Wallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BIP39_SEED)
await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)
assert.notEqual(account.frontier, undefined)
assert.notEqual(account.frontier, null)
assert.equals(typeof account.frontier, 'string')
+
+ wallet.destroy()
})
await test('should get balance, frontier, and representative for multiple accounts', async () => {
const accounts = await wallet.refresh(rpc, 0, 2)
assert.equals(accounts.length, 1)
assert.ok(accounts[0] instanceof Account)
+
+ wallet.destroy()
})
await test('should handle failure gracefully', async () => {
const wallet = await Bip44Wallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BIP39_SEED)
await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)
await assert.doesNotReject(wallet.refresh(rpc, 0, 20))
+
+ wallet.destroy()
})
})
\r
'use strict'\r
\r
-import { assert, suite, test } from '#GLOBALS.mjs'\r
-import { NANO_TEST_VECTORS } from '#test/TEST_VECTORS.js'\r
-import { SendBlock, ReceiveBlock, ChangeBlock } from '#dist/main.js'\r
+import { assert, suite, test } from './GLOBALS.mjs'\r
+import { NANO_TEST_VECTORS } from './VECTORS.js'\r
+import { SendBlock, ReceiveBlock, ChangeBlock } from '../dist/main.min.js'\r
\r
await suite('Valid blocks', async () => {\r
+\r
await test('should not allow negative balances', async () => {\r
assert.throws(() => {\r
- const block = new SendBlock(\r
+ new SendBlock(\r
NANO_TEST_VECTORS.ADDRESS_0,\r
'7000000000000000000000000000000',\r
NANO_TEST_VECTORS.ADDRESS_1,\r
})\r
\r
await suite('Block signing tests using official test vectors', async () => {\r
+\r
await test('should create a valid signature for an open block', async () => {\r
const block = new ReceiveBlock(\r
NANO_TEST_VECTORS.OPEN_BLOCK.account,\r
NANO_TEST_VECTORS.OPEN_BLOCK.work\r
)\r
await block.sign(NANO_TEST_VECTORS.OPEN_BLOCK.key)\r
- assert.equals(await block.hash(), NANO_TEST_VECTORS.OPEN_BLOCK.hash)\r
+ assert.equals(block.hash, NANO_TEST_VECTORS.OPEN_BLOCK.hash)\r
assert.equals(block.signature, NANO_TEST_VECTORS.OPEN_BLOCK.signature)\r
})\r
\r
NANO_TEST_VECTORS.RECEIVE_BLOCK.work\r
)\r
await block.sign(NANO_TEST_VECTORS.RECEIVE_BLOCK.key)\r
- assert.equals(await block.hash(), NANO_TEST_VECTORS.RECEIVE_BLOCK.hash)\r
+ assert.equals(block.hash, NANO_TEST_VECTORS.RECEIVE_BLOCK.hash)\r
assert.equals(block.signature, NANO_TEST_VECTORS.RECEIVE_BLOCK.signature)\r
})\r
\r
NANO_TEST_VECTORS.RECEIVE_BLOCK.previous\r
)\r
await block.sign(NANO_TEST_VECTORS.RECEIVE_BLOCK.key)\r
- assert.equals(await block.hash(), NANO_TEST_VECTORS.RECEIVE_BLOCK.hash)\r
+ assert.equals(block.hash, NANO_TEST_VECTORS.RECEIVE_BLOCK.hash)\r
assert.equals(block.signature, NANO_TEST_VECTORS.RECEIVE_BLOCK.signature)\r
assert.equals(block.work, '')\r
})\r
NANO_TEST_VECTORS.SEND_BLOCK.work\r
)\r
await block.sign(NANO_TEST_VECTORS.SEND_BLOCK.key)\r
- assert.equals(await block.hash(), NANO_TEST_VECTORS.SEND_BLOCK.hash)\r
+ assert.equals(block.hash, NANO_TEST_VECTORS.SEND_BLOCK.hash)\r
assert.equals(block.signature, NANO_TEST_VECTORS.SEND_BLOCK.signature)\r
})\r
\r
NANO_TEST_VECTORS.SEND_BLOCK.previous\r
)\r
await block.sign(NANO_TEST_VECTORS.SEND_BLOCK.key)\r
- assert.equals(await block.hash(), NANO_TEST_VECTORS.SEND_BLOCK.hash)\r
+ assert.equals(block.hash, NANO_TEST_VECTORS.SEND_BLOCK.hash)\r
assert.equals(block.signature, NANO_TEST_VECTORS.SEND_BLOCK.signature)\r
assert.equals(block.work, '')\r
})\r
\r
'use strict'\r
\r
-import { assert, skip, suite, test } from '#GLOBALS.mjs'\r
-import { RAW_MAX, NANO_TEST_VECTORS } from '#test/TEST_VECTORS.js'\r
-import { Bip44Wallet, Account, SendBlock, Rpc, Tools } from '#dist/main.js'\r
+import { assert, suite, test } from './GLOBALS.mjs'\r
+import { RAW_MAX, NANO_TEST_VECTORS } from './VECTORS.js'\r
+import { Bip44Wallet, Account, SendBlock, Rpc, Tools } from '../dist/main.min.js'\r
\r
let rpc\r
//@ts-ignore\r
}\r
\r
await suite('unit conversion tests', async () => {\r
+\r
await test('should convert nano to raw', async () => {\r
const result = await Tools.convert('1', 'NANO', 'RAW')\r
assert.equals(result, '1000000000000000000000000000000')\r
})\r
\r
await suite('signature tests', async () => {\r
+\r
await test('should sign data with a single parameter', async () => {\r
const result = await Tools.sign(NANO_TEST_VECTORS.PRIVATE_0, 'miro@metsanheimo.fi')\r
assert.equals(result, 'FECB9B084065ADC969904B55A0099C63746B68DF41FECB713244D387EED83A80B9D4907278C5EBC0998A5FC8BA597FBAAABBFCE0ABD2CA2212ACFE788637040C')\r
await sendBlock.sign(account.privateKey ?? '')\r
const valid = await sendBlock.verify(account.publicKey)\r
assert.equals(valid, true)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('should reject a block using the wrong public key', async () => {\r
sendBlock.account = Account.fromAddress('nano_1q3hqecaw15cjt7thbtxu3pbzr1eihtzzpzxguoc37bj1wc5ffoh7w74gi6p')\r
const valid = await sendBlock.verify(account.publicKey)\r
assert.equals(valid, false)\r
+\r
+ wallet.destroy()\r
})\r
\r
await test('sweeper throws without required parameters', async () => {\r
- //@ts-expect-error\r
await assert.rejects(Tools.sweep(),\r
'Missing required sweep arguments')\r
})\r
\r
- await skip('sweeper fails gracefully for ineligible accounts', async () => {\r
+ await test('sweeper fails gracefully for ineligible accounts', { skip: true }, async () => {\r
const wallet = await Bip44Wallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BIP39_SEED)\r
await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)\r
const results = await Tools.sweep(rpc, wallet, NANO_TEST_VECTORS.ADDRESS_1)\r
assert.ok(results)\r
assert.equals(results.length, 1)\r
+\r
+ wallet.destroy()\r
})\r
})\r
"module": "ESNext",
"moduleResolution": "Bundler",
"declaration": true,
- "noEmit": false,
- "outDir": "./dist",
+ "emitDeclarationOnly": true,
+ "declarationDir": "./types",
"alwaysStrict": true,
"downlevelIteration": false,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
+ "isolatedModules": true,
"noErrorTruncation": true,
"noFallthroughCasesInSwitch": true,
- "strict": true
+ "strict": true,
+ "rootDir": "src"
},
"include": [
"src/main.ts",