diff options
author | Casper Beyer <caspervonb@pm.me> | 2021-02-02 19:05:46 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-02 12:05:46 +0100 |
commit | 6abf126c2a7a451cded8c6b5e6ddf1b69c84055d (patch) | |
tree | fd94c013a19fcb38954844085821ec1601c20e18 /std/hash | |
parent | a2b5d44f1aa9d64f448a2a3cc2001272e2f60b98 (diff) |
chore: remove std directory (#9361)
This removes the std folder from the tree.
Various parts of the tests are pretty tightly dependent
on std (47 direct imports and 75 indirect imports, not
counting the cli tests that use them as fixtures) so I've
added std as a submodule for now.
Diffstat (limited to 'std/hash')
33 files changed, 0 insertions, 6219 deletions
diff --git a/std/hash/README.md b/std/hash/README.md deleted file mode 100644 index ec5d068e9..000000000 --- a/std/hash/README.md +++ /dev/null @@ -1,83 +0,0 @@ -# std/hash - -## Usage - -### Creating new hash instance - -You can create a new Hasher instance by calling `createHash` defined in mod.ts. - -```ts -import { createHash } from "https://deno.land/std@$STD_VERSION/hash/mod.ts"; - -const hash = createHash("md5"); -// ... -``` - -### Using hash instance - -You can use `update` method to feed data into your hash instance. Call `digest` -method to retrive final hash value in ArrayBuffer. - -```ts -import { createHash } from "https://deno.land/std@$STD_VERSION/hash/mod.ts"; - -const hash = createHash("md5"); -hash.update("Your data here"); -const final = hash.digest(); // returns ArrayBuffer. -``` - -Please note that `digest` invalidates the hash instance's internal state. -Calling `digest` more than once will throw an Error. - -```ts -import { createHash } from "https://deno.land/std@$STD_VERSION/hash/mod.ts"; - -const hash = createHash("md5"); -hash.update("Your data here"); -const final1 = hash.digest(); // returns ArrayBuffer. -const final2 = hash.digest(); // throws Error. -``` - -If you need final hash in string formats, call `toString` method with output -format. - -Supported formats are `hex` and `base64` and default format is `hex`. - -```ts -import { createHash } from "https://deno.land/std@$STD_VERSION/hash/mod.ts"; - -const hash = createHash("md5"); -hash.update("Your data here"); -const hashInHex = hash.toString(); // returns 5fe084ee423ff7e0c7709e9437cee89d -``` - -```ts -import { createHash } from "https://deno.land/std@$STD_VERSION/hash/mod.ts"; - -const hash = createHash("md5"); -hash.update("Your data here"); -const hashInBase64 = hash.toString("base64"); // returns X+CE7kI/9+DHcJ6UN87onQ== -``` - -### Supported algorithms - -Following algorithms are supported. - -- md2 -- md4 -- md5 -- ripemd160 -- ripemd320 -- sha1 -- sha224 -- sha256 -- sha384 -- sha512 -- sha3-224 -- sha3-256 -- sha3-384 -- sha3-512 -- keccak224 -- keccak256 -- keccak384 -- keccak512 diff --git a/std/hash/_fnv/fnv32.ts b/std/hash/_fnv/fnv32.ts deleted file mode 100644 index 679d44a62..000000000 --- a/std/hash/_fnv/fnv32.ts +++ /dev/null @@ -1,79 +0,0 @@ -// Ported from Go: -// https://github.com/golang/go/tree/go1.13.10/src/hash/fnv/fnv.go -// Copyright 2011 The Go Authors. All rights reserved. BSD license. -// https://github.com/golang/go/blob/master/LICENSE -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -import { mul32 } from "./util.ts"; - -const offset32 = 2166136261; -const prime32 = 16777619; - -abstract class Fnv32Base<T> { - #state: number; - - constructor() { - this.#state = offset32; - } - - protected _updateState(newState: number): void { - this.#state = newState; - } - - reset(): void { - this.#state = offset32; - } - - abstract write(data: Uint8Array): T; - - size(): number { - return 4; - } - - blockSize(): number { - return 1; - } - - sum32(): number { - return this.#state; - } - - sum(): Uint8Array { - return Uint8Array.from([ - (this.#state >> 24) & 0xff, - (this.#state >> 16) & 0xff, - (this.#state >> 8) & 0xff, - this.#state & 0xff, - ]); - } -} - -/** Fnv32 hash */ -export class Fnv32 extends Fnv32Base<Fnv32> { - write(data: Uint8Array): Fnv32 { - let hash = this.sum32(); - - data.forEach((c) => { - hash = mul32(hash, prime32); - hash ^= c; - }); - - this._updateState(hash); - return this; - } -} - -/** Fnv32a hash */ -export class Fnv32a extends Fnv32Base<Fnv32a> { - write(data: Uint8Array): Fnv32a { - let hash = this.sum32(); - - data.forEach((c) => { - hash ^= c; - hash = mul32(hash, prime32); - }); - - this._updateState(hash); - return this; - } -} diff --git a/std/hash/_fnv/fnv64.ts b/std/hash/_fnv/fnv64.ts deleted file mode 100644 index 882636d0e..000000000 --- a/std/hash/_fnv/fnv64.ts +++ /dev/null @@ -1,89 +0,0 @@ -// Ported from Go: -// https://github.com/golang/go/tree/go1.13.10/src/hash/fnv/fnv.go -// Copyright 2011 The Go Authors. All rights reserved. BSD license. -// https://github.com/golang/go/blob/master/LICENSE -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -import { mul64 } from "./util.ts"; - -const offset64Lo = 2216829733; -const offset64Hi = 3421674724; -const prime64Lo = 435; -const prime64Hi = 256; - -abstract class Fnv64Base<T> { - #stateHi: number; - #stateLo: number; - - constructor() { - this.#stateHi = offset64Hi; - this.#stateLo = offset64Lo; - } - - protected _updateState([newStateHi, newStateLo]: [number, number]): void { - this.#stateHi = newStateHi; - this.#stateLo = newStateLo; - } - - reset(): void { - this.#stateHi = offset64Hi; - this.#stateLo = offset64Lo; - } - - abstract write(data: Uint8Array): T; - - size(): number { - return 8; - } - - blockSize(): number { - return 1; - } - - sum64(): [number, number] { - return [this.#stateHi, this.#stateLo]; - } - - sum(): Uint8Array { - return Uint8Array.from([ - (this.#stateHi >> 24) & 0xff, - (this.#stateHi >> 16) & 0xff, - (this.#stateHi >> 8) & 0xff, - this.#stateHi & 0xff, - (this.#stateLo >> 24) & 0xff, - (this.#stateLo >> 16) & 0xff, - (this.#stateLo >> 8) & 0xff, - this.#stateLo & 0xff, - ]); - } -} - -/** Fnv64 hash */ -export class Fnv64 extends Fnv64Base<Fnv64> { - write(data: Uint8Array): Fnv64 { - let [hashHi, hashLo] = this.sum64(); - - data.forEach((c) => { - [hashHi, hashLo] = mul64([hashHi, hashLo], [prime64Hi, prime64Lo]); - hashLo ^= c; - }); - - this._updateState([hashHi, hashLo]); - return this; - } -} - -/** Fnv64a hash */ -export class Fnv64a extends Fnv64Base<Fnv64a> { - write(data: Uint8Array): Fnv64 { - let [hashHi, hashLo] = this.sum64(); - - data.forEach((c) => { - hashLo ^= c; - [hashHi, hashLo] = mul64([hashHi, hashLo], [prime64Hi, prime64Lo]); - }); - - this._updateState([hashHi, hashLo]); - return this; - } -} diff --git a/std/hash/_fnv/util.ts b/std/hash/_fnv/util.ts deleted file mode 100644 index 8afed8e82..000000000 --- a/std/hash/_fnv/util.ts +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -function n16(n: number): number { - return n & 0xffff; -} - -function n32(n: number): number { - return n >>> 0; -} - -function add32WithCarry(a: number, b: number): [number, number] { - const added = n32(a) + n32(b); - return [n32(added), added > 0xffffffff ? 1 : 0]; -} - -function mul32WithCarry(a: number, b: number): [number, number] { - const al = n16(a); - const ah = n16(a >>> 16); - const bl = n16(b); - const bh = n16(b >>> 16); - - const [t, tc] = add32WithCarry(al * bh, ah * bl); - const [n, nc] = add32WithCarry(al * bl, n32(t << 16)); - const carry = nc + (tc << 16) + n16(t >>> 16) + ah * bh; - - return [n, carry]; -} - -/** - * mul32 performs 32-bit multiplication, a * b - * @param a - * @param b - */ -export function mul32(a: number, b: number): number { - // https://stackoverflow.com/a/28151933 - const al = n16(a); - const ah = a - al; - return n32(n32(ah * b) + al * b); -} - -/** - * mul64 performs 64-bit multiplication with two 32-bit words - * @param [ah, al] - * @param [bh, bl] - */ -export function mul64( - [ah, al]: [number, number], - [bh, bl]: [number, number], -): [number, number] { - const [n, c] = mul32WithCarry(al, bl); - return [n32(mul32(al, bh) + mul32(ah, bl) + c), n]; -} diff --git a/std/hash/_fnv/util_test.ts b/std/hash/_fnv/util_test.ts deleted file mode 100644 index fb9dd3208..000000000 --- a/std/hash/_fnv/util_test.ts +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -import { assertEquals } from "../../testing/asserts.ts"; -import { mul32, mul64 } from "./util.ts"; - -Deno.test("[hash/fnv/util] mul32", () => { - assertEquals(mul32(0xffffffff, 0xffffffff), 1); - assertEquals(mul32(0x12345678, 0xdeadbeef), 0x5621ca08); - assertEquals(mul32(0xf626f430, 0xff7469f1), 0x2a939130); - assertEquals(mul32(0x543f9412, 0x8a4aa84f), 0x39fe818e); - assertEquals(mul32(0x8ee170d1, 0x2fbbb9ec), 0x6a0609ac); - assertEquals(mul32(0xea3b3a14, 0xa397bd0a), 0xddfd08c8); - assertEquals(mul32(0x93f8536b, 0xa79e3c04), 0xcc7861ac); - assertEquals(mul32(0xf97dab98, 0xed526241), 0x2348c198); - assertEquals(mul32(0x35500191, 0xd5012447), 0xaff9d337); - assertEquals(mul32(0x471dde47, 0xaaa4950c), 0x4341be54); - assertEquals(mul32(0xd633970d, 0xa9bc2bcd), 0xb43b2469); - assertEquals(mul32(0xc60898cc, 0xbfe7dcc4), 0x15f84c30); -}); - -Deno.test("[hash/fnv/util] mul64", () => { - assertEquals(mul64([0xffffffff, 0xffffffff], [0xffffffff, 0xffffffff]), [ - 0, - 1, - ]); - assertEquals(mul64([0x12345678, 0xdeadbeef], [0xcafebabe, 0xbaadf00d]), [ - 0xc801c86b, - 0xdf55c223, - ]); - assertEquals(mul64([0xdc479aed, 0x24bc71a3], [0x543717c1, 0x4b6056b9]), [ - 0x56c7ec8f, - 0x387ae0cb, - ]); - assertEquals(mul64([0xb84936ae, 0xb84becd2], [0x2864edd1, 0x14ee13cc]), [ - 0xd87e9171, - 0x12504d58, - ]); - assertEquals(mul64([0xb0b73e95, 0x3f5cc701], [0x6c7b30b8, 0xcd7f0f9e]), [ - 0x570551ee, - 0x116ae19e, - ]); - assertEquals(mul64([0xc237b433, 0x160b50bf], [0x3f937c23, 0xf26175f7]), [ - 0x48a1d118, - 0x97313349, - ]); - assertEquals(mul64([0x386242fd, 0x6baa0fc0], [0xf81f7e23, 0xbe172381]), [ - 0x4799f2a3, - 0x6b192fc0, - ]); - assertEquals(mul64([0x5afc8714, 0x902180d1], [0xa7068c96, 0xb859bb4d]), [ - 0xb4589d29, - 0xd3d569dd, - ]); - assertEquals(mul64([0xb4e86a68, 0x619bee92], [0xd67560fa, 0x736982a7]), [ - 0x72c73b5d, - 0x4bc0c53e, - ]); - assertEquals(mul64([0xfc8b5561, 0xbf91d6d5], [0x2bcb029a, 0xa144ead3]), [ - 0x2da439a7, - 0x3926c38f, - ]); - assertEquals(mul64([0x47b62fae, 0xffe8cb4c], [0xbda77111, 0x6cad4968]), [ - 0x9d9b7832, - 0xcae742e0, - ]); - assertEquals(mul64([0xc9160fc1, 0xd96e085b], [0x3adfd031, 0x3f75e557]), [ - 0xe4d0bf23, - 0x88753ded, - ]); -}); diff --git a/std/hash/_sha3/keccak.ts b/std/hash/_sha3/keccak.ts deleted file mode 100644 index 403a2dcb0..000000000 --- a/std/hash/_sha3/keccak.ts +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -import { Sponge } from "./sponge.ts"; -import { keccakf } from "./keccakf.ts"; - -/** Keccak-224 hash */ -export class Keccak224 extends Sponge { - constructor() { - super({ - bitsize: 224, - rate: 144, - dsbyte: 1, - permutator: keccakf, - }); - } -} - -/** Keccak-256 hash */ -export class Keccak256 extends Sponge { - constructor() { - super({ - bitsize: 256, - rate: 136, - dsbyte: 1, - permutator: keccakf, - }); - } -} - -/** Keccak-384 hash */ -export class Keccak384 extends Sponge { - constructor() { - super({ - bitsize: 384, - rate: 104, - dsbyte: 1, - permutator: keccakf, - }); - } -} - -/** Keccak-512 hash */ -export class Keccak512 extends Sponge { - constructor() { - super({ - bitsize: 512, - rate: 72, - dsbyte: 1, - permutator: keccakf, - }); - } -} diff --git a/std/hash/_sha3/keccakf.ts b/std/hash/_sha3/keccakf.ts deleted file mode 100644 index 0ba2b870c..000000000 --- a/std/hash/_sha3/keccakf.ts +++ /dev/null @@ -1,790 +0,0 @@ -// Ported from Go: -// https://github.com/golang/crypto/blob/master/sha3/keccakf.go -// Copyright 2011 The Go Authors. All rights reserved. BSD license. -// https://github.com/golang/go/blob/master/LICENSE -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -const KECCAK_ROUNDS = 24; -const KECCAK_RC: number[] = [ - 0x1, - 0x0, - 0x8082, - 0x0, - 0x808a, - 0x80000000, - 0x80008000, - 0x80000000, - 0x808b, - 0x0, - 0x80000001, - 0x0, - 0x80008081, - 0x80000000, - 0x8009, - 0x80000000, - 0x8a, - 0x0, - 0x88, - 0x0, - 0x80008009, - 0x0, - 0x8000000a, - 0x0, - 0x8000808b, - 0x0, - 0x8b, - 0x80000000, - 0x8089, - 0x80000000, - 0x8003, - 0x80000000, - 0x8002, - 0x80000000, - 0x80, - 0x80000000, - 0x800a, - 0x0, - 0x8000000a, - 0x80000000, - 0x80008081, - 0x80000000, - 0x8080, - 0x80000000, - 0x80000001, - 0x0, - 0x80008008, - 0x80000000, -]; - -/** keccak1600 permutation function */ -export function keccakf(state: Uint8Array): void { - const s = new Uint32Array(state.buffer); - let bc0 = 0; - let bc1 = 0; - let bc2 = 0; - let bc3 = 0; - let bc4 = 0; - let bc5 = 0; - let bc6 = 0; - let bc7 = 0; - let bc8 = 0; - let bc9 = 0; - let d0 = 0; - let d1 = 0; - let d2 = 0; - let d3 = 0; - let d4 = 0; - let d5 = 0; - let d6 = 0; - let d7 = 0; - let d8 = 0; - let d9 = 0; - let t0 = 0; - let t1 = 0; - - for (let n = 0; n < KECCAK_ROUNDS * 2; n += 8) { - // Round 1 - bc0 = s[0] ^ s[10] ^ s[20] ^ s[30] ^ s[40]; - bc1 = s[1] ^ s[11] ^ s[21] ^ s[31] ^ s[41]; - bc2 = s[2] ^ s[12] ^ s[22] ^ s[32] ^ s[42]; - bc3 = s[3] ^ s[13] ^ s[23] ^ s[33] ^ s[43]; - bc4 = s[4] ^ s[14] ^ s[24] ^ s[34] ^ s[44]; - bc5 = s[5] ^ s[15] ^ s[25] ^ s[35] ^ s[45]; - bc6 = s[6] ^ s[16] ^ s[26] ^ s[36] ^ s[46]; - bc7 = s[7] ^ s[17] ^ s[27] ^ s[37] ^ s[47]; - bc8 = s[8] ^ s[18] ^ s[28] ^ s[38] ^ s[48]; - bc9 = s[9] ^ s[19] ^ s[29] ^ s[39] ^ s[49]; - - d0 = bc8 ^ ((bc2 << 1) | (bc3 >>> 31)); - d1 = bc9 ^ ((bc3 << 1) | (bc2 >>> 31)); - d2 = bc0 ^ ((bc4 << 1) | (bc5 >>> 31)); - d3 = bc1 ^ ((bc5 << 1) | (bc4 >>> 31)); - d4 = bc2 ^ ((bc6 << 1) | (bc7 >>> 31)); - d5 = bc3 ^ ((bc7 << 1) | (bc6 >>> 31)); - d6 = bc4 ^ ((bc8 << 1) | (bc9 >>> 31)); - d7 = bc5 ^ ((bc9 << 1) | (bc8 >>> 31)); - d8 = bc6 ^ ((bc0 << 1) | (bc1 >>> 31)); - d9 = bc7 ^ ((bc1 << 1) | (bc0 >>> 31)); - - bc0 = s[0] ^ d0; - bc1 = s[1] ^ d1; - t0 = s[12] ^ d2; - t1 = s[13] ^ d3; - bc2 = (t1 << 12) | (t0 >>> 20); - bc3 = (t0 << 12) | (t1 >>> 20); - t0 = s[24] ^ d4; - t1 = s[25] ^ d5; - bc4 = (t1 << 11) | (t0 >>> 21); - bc5 = (t0 << 11) | (t1 >>> 21); - t0 = s[36] ^ d6; - t1 = s[37] ^ d7; - bc6 = (t0 << 21) | (t1 >>> 11); - bc7 = (t1 << 21) | (t0 >>> 11); - t0 = s[48] ^ d8; - t1 = s[49] ^ d9; - bc8 = (t0 << 14) | (t1 >>> 18); - bc9 = (t1 << 14) | (t0 >>> 18); - s[0] = bc0 ^ (bc4 & ~bc2) ^ KECCAK_RC[n]; - s[1] = bc1 ^ (bc5 & ~bc3) ^ KECCAK_RC[n + 1]; - s[12] = bc2 ^ (bc6 & ~bc4); - s[13] = bc3 ^ (bc7 & ~bc5); - s[24] = bc4 ^ (bc8 & ~bc6); - s[25] = bc5 ^ (bc9 & ~bc7); - s[36] = bc6 ^ (bc0 & ~bc8); - s[37] = bc7 ^ (bc1 & ~bc9); - s[48] = bc8 ^ (bc2 & ~bc0); - s[49] = bc9 ^ (bc3 & ~bc1); - - t0 = s[20] ^ d0; - t1 = s[21] ^ d1; - bc4 = (t0 << 3) | (t1 >>> 29); - bc5 = (t1 << 3) | (t0 >>> 29); - t0 = s[32] ^ d2; - t1 = s[33] ^ d3; - bc6 = (t1 << 13) | (t0 >>> 19); - bc7 = (t0 << 13) | (t1 >>> 19); - t0 = s[44] ^ d4; - t1 = s[45] ^ d5; - bc8 = (t1 << 29) | (t0 >>> 3); - bc9 = (t0 << 29) | (t1 >>> 3); - t0 = s[6] ^ d6; - t1 = s[7] ^ d7; - bc0 = (t0 << 28) | (t1 >>> 4); - bc1 = (t1 << 28) | (t0 >>> 4); - t0 = s[18] ^ d8; - t1 = s[19] ^ d9; - bc2 = (t0 << 20) | (t1 >>> 12); - bc3 = (t1 << 20) | (t0 >>> 12); - s[20] = bc0 ^ (bc4 & ~bc2); - s[21] = bc1 ^ (bc5 & ~bc3); - s[32] = bc2 ^ (bc6 & ~bc4); - s[33] = bc3 ^ (bc7 & ~bc5); - s[44] = bc4 ^ (bc8 & ~bc6); - s[45] = bc5 ^ (bc9 & ~bc7); - s[6] = bc6 ^ (bc0 & ~bc8); - s[7] = bc7 ^ (bc1 & ~bc9); - s[18] = bc8 ^ (bc2 & ~bc0); - s[19] = bc9 ^ (bc3 & ~bc1); - - t0 = s[40] ^ d0; - t1 = s[41] ^ d1; - bc8 = (t0 << 18) | (t1 >>> 14); - bc9 = (t1 << 18) | (t0 >>> 14); - t0 = s[2] ^ d2; - t1 = s[3] ^ d3; - bc0 = (t0 << 1) | (t1 >>> 31); - bc1 = (t1 << 1) | (t0 >>> 31); - t0 = s[14] ^ d4; - t1 = s[15] ^ d5; - bc2 = (t0 << 6) | (t1 >>> 26); - bc3 = (t1 << 6) | (t0 >>> 26); - t0 = s[26] ^ d6; - t1 = s[27] ^ d7; - bc4 = (t0 << 25) | (t1 >>> 7); - bc5 = (t1 << 25) | (t0 >>> 7); - t0 = s[38] ^ d8; - t1 = s[39] ^ d9; - bc6 = (t0 << 8) | (t1 >>> 24); - bc7 = (t1 << 8) | (t0 >>> 24); - s[40] = bc0 ^ (bc4 & ~bc2); - s[41] = bc1 ^ (bc5 & ~bc3); - s[2] = bc2 ^ (bc6 & ~bc4); - s[3] = bc3 ^ (bc7 & ~bc5); - s[14] = bc4 ^ (bc8 & ~bc6); - s[15] = bc5 ^ (bc9 & ~bc7); - s[26] = bc6 ^ (bc0 & ~bc8); - s[27] = bc7 ^ (bc1 & ~bc9); - s[38] = bc8 ^ (bc2 & ~bc0); - s[39] = bc9 ^ (bc3 & ~bc1); - - t0 = s[10] ^ d0; - t1 = s[11] ^ d1; - bc2 = (t1 << 4) | (t0 >>> 28); - bc3 = (t0 << 4) | (t1 >>> 28); - t0 = s[22] ^ d2; - t1 = s[23] ^ d3; - bc4 = (t0 << 10) | (t1 >>> 22); - bc5 = (t1 << 10) | (t0 >>> 22); - t0 = s[34] ^ d4; - t1 = s[35] ^ d5; - bc6 = (t0 << 15) | (t1 >>> 17); - bc7 = (t1 << 15) | (t0 >>> 17); - t0 = s[46] ^ d6; - t1 = s[47] ^ d7; - bc8 = (t1 << 24) | (t0 >>> 8); - bc9 = (t0 << 24) | (t1 >>> 8); - t0 = s[8] ^ d8; - t1 = s[9] ^ d9; - bc0 = (t0 << 27) | (t1 >>> 5); - bc1 = (t1 << 27) | (t0 >>> 5); - s[10] = bc0 ^ (bc4 & ~bc2); - s[11] = bc1 ^ (bc5 & ~bc3); - s[22] = bc2 ^ (bc6 & ~bc4); - s[23] = bc3 ^ (bc7 & ~bc5); - s[34] = bc4 ^ (bc8 & ~bc6); - s[35] = bc5 ^ (bc9 & ~bc7); - s[46] = bc6 ^ (bc0 & ~bc8); - s[47] = bc7 ^ (bc1 & ~bc9); - s[8] = bc8 ^ (bc2 & ~bc0); - s[9] = bc9 ^ (bc3 & ~bc1); - - t0 = s[30] ^ d0; - t1 = s[31] ^ d1; - bc6 = (t1 << 9) | (t0 >>> 23); - bc7 = (t0 << 9) | (t1 >>> 23); - t0 = s[42] ^ d2; - t1 = s[43] ^ d3; - bc8 = (t0 << 2) | (t1 >>> 30); - bc9 = (t1 << 2) | (t0 >>> 30); - t0 = s[4] ^ d4; - t1 = s[5] ^ d5; - bc0 = (t1 << 30) | (t0 >>> 2); - bc1 = (t0 << 30) | (t1 >>> 2); - t0 = s[16] ^ d6; - t1 = s[17] ^ d7; - bc2 = (t1 << 23) | (t0 >>> 9); - bc3 = (t0 << 23) | (t1 >>> 9); - t0 = s[28] ^ d8; - t1 = s[29] ^ d9; - bc4 = (t1 << 7) | (t0 >>> 25); - bc5 = (t0 << 7) | (t1 >>> 25); - s[30] = bc0 ^ (bc4 & ~bc2); - s[31] = bc1 ^ (bc5 & ~bc3); - s[42] = bc2 ^ (bc6 & ~bc4); - s[43] = bc3 ^ (bc7 & ~bc5); - s[4] = bc4 ^ (bc8 & ~bc6); - s[5] = bc5 ^ (bc9 & ~bc7); - s[16] = bc6 ^ (bc0 & ~bc8); - s[17] = bc7 ^ (bc1 & ~bc9); - s[28] = bc8 ^ (bc2 & ~bc0); - s[29] = bc9 ^ (bc3 & ~bc1); - - // Round 2 - bc0 = s[0] ^ s[10] ^ s[20] ^ s[30] ^ s[40]; - bc1 = s[1] ^ s[11] ^ s[21] ^ s[31] ^ s[41]; - bc2 = s[2] ^ s[12] ^ s[22] ^ s[32] ^ s[42]; - bc3 = s[3] ^ s[13] ^ s[23] ^ s[33] ^ s[43]; - bc4 = s[4] ^ s[14] ^ s[24] ^ s[34] ^ s[44]; - bc5 = s[5] ^ s[15] ^ s[25] ^ s[35] ^ s[45]; - bc6 = s[6] ^ s[16] ^ s[26] ^ s[36] ^ s[46]; - bc7 = s[7] ^ s[17] ^ s[27] ^ s[37] ^ s[47]; - bc8 = s[8] ^ s[18] ^ s[28] ^ s[38] ^ s[48]; - bc9 = s[9] ^ s[19] ^ s[29] ^ s[39] ^ s[49]; - - d0 = bc8 ^ ((bc2 << 1) | (bc3 >>> 31)); - d1 = bc9 ^ ((bc3 << 1) | (bc2 >>> 31)); - d2 = bc0 ^ ((bc4 << 1) | (bc5 >>> 31)); - d3 = bc1 ^ ((bc5 << 1) | (bc4 >>> 31)); - d4 = bc2 ^ ((bc6 << 1) | (bc7 >>> 31)); - d5 = bc3 ^ ((bc7 << 1) | (bc6 >>> 31)); - d6 = bc4 ^ ((bc8 << 1) | (bc9 >>> 31)); - d7 = bc5 ^ ((bc9 << 1) | (bc8 >>> 31)); - d8 = bc6 ^ ((bc0 << 1) | (bc1 >>> 31)); - d9 = bc7 ^ ((bc1 << 1) | (bc0 >>> 31)); - - bc0 = s[0] ^ d0; - bc1 = s[1] ^ d1; - t0 = s[32] ^ d2; - t1 = s[33] ^ d3; - bc2 = (t1 << 12) | (t0 >>> 20); - bc3 = (t0 << 12) | (t1 >>> 20); - t0 = s[14] ^ d4; - t1 = s[15] ^ d5; - bc4 = (t1 << 11) | (t0 >>> 21); - bc5 = (t0 << 11) | (t1 >>> 21); - t0 = s[46] ^ d6; - t1 = s[47] ^ d7; - bc6 = (t0 << 21) | (t1 >>> 11); - bc7 = (t1 << 21) | (t0 >>> 11); - t0 = s[28] ^ d8; - t1 = s[29] ^ d9; - bc8 = (t0 << 14) | (t1 >>> 18); - bc9 = (t1 << 14) | (t0 >>> 18); - s[0] = bc0 ^ (bc4 & ~bc2) ^ KECCAK_RC[n + 2]; - s[1] = bc1 ^ (bc5 & ~bc3) ^ KECCAK_RC[n + 3]; - s[32] = bc2 ^ (bc6 & ~bc4); - s[33] = bc3 ^ (bc7 & ~bc5); - s[14] = bc4 ^ (bc8 & ~bc6); - s[15] = bc5 ^ (bc9 & ~bc7); - s[46] = bc6 ^ (bc0 & ~bc8); - s[47] = bc7 ^ (bc1 & ~bc9); - s[28] = bc8 ^ (bc2 & ~bc0); - s[29] = bc9 ^ (bc3 & ~bc1); - - t0 = s[40] ^ d0; - t1 = s[41] ^ d1; - bc4 = (t0 << 3) | (t1 >>> 29); - bc5 = (t1 << 3) | (t0 >>> 29); - t0 = s[22] ^ d2; - t1 = s[23] ^ d3; - bc6 = (t1 << 13) | (t0 >>> 19); - bc7 = (t0 << 13) | (t1 >>> 19); - t0 = s[4] ^ d4; - t1 = s[5] ^ d5; - bc8 = (t1 << 29) | (t0 >>> 3); - bc9 = (t0 << 29) | (t1 >>> 3); - t0 = s[36] ^ d6; - t1 = s[37] ^ d7; - bc0 = (t0 << 28) | (t1 >>> 4); - bc1 = (t1 << 28) | (t0 >>> 4); - t0 = s[18] ^ d8; - t1 = s[19] ^ d9; - bc2 = (t0 << 20) | (t1 >>> 12); - bc3 = (t1 << 20) | (t0 >>> 12); - s[40] = bc0 ^ (bc4 & ~bc2); - s[41] = bc1 ^ (bc5 & ~bc3); - s[22] = bc2 ^ (bc6 & ~bc4); - s[23] = bc3 ^ (bc7 & ~bc5); - s[4] = bc4 ^ (bc8 & ~bc6); - s[5] = bc5 ^ (bc9 & ~bc7); - s[36] = bc6 ^ (bc0 & ~bc8); - s[37] = bc7 ^ (bc1 & ~bc9); - s[18] = bc8 ^ (bc2 & ~bc0); - s[19] = bc9 ^ (bc3 & ~bc1); - - t0 = s[30] ^ d0; - t1 = s[31] ^ d1; - bc8 = (t0 << 18) | (t1 >>> 14); - bc9 = (t1 << 18) | (t0 >>> 14); - t0 = s[12] ^ d2; - t1 = s[13] ^ d3; - bc0 = (t0 << 1) | (t1 >>> 31); - bc1 = (t1 << 1) | (t0 >>> 31); - t0 = s[44] ^ d4; - t1 = s[45] ^ d5; - bc2 = (t0 << 6) | (t1 >>> 26); - bc3 = (t1 << 6) | (t0 >>> 26); - t0 = s[26] ^ d6; - t1 = s[27] ^ d7; - bc4 = (t0 << 25) | (t1 >>> 7); - bc5 = (t1 << 25) | (t0 >>> 7); - t0 = s[8] ^ d8; - t1 = s[9] ^ d9; - bc6 = (t0 << 8) | (t1 >>> 24); - bc7 = (t1 << 8) | (t0 >>> 24); - s[30] = bc0 ^ (bc4 & ~bc2); - s[31] = bc1 ^ (bc5 & ~bc3); - s[12] = bc2 ^ (bc6 & ~bc4); - s[13] = bc3 ^ (bc7 & ~bc5); - s[44] = bc4 ^ (bc8 & ~bc6); - s[45] = bc5 ^ (bc9 & ~bc7); - s[26] = bc6 ^ (bc0 & ~bc8); - s[27] = bc7 ^ (bc1 & ~bc9); - s[8] = bc8 ^ (bc2 & ~bc0); - s[9] = bc9 ^ (bc3 & ~bc1); - - t0 = s[20] ^ d0; - t1 = s[21] ^ d1; - bc2 = (t1 << 4) | (t0 >>> 28); - bc3 = (t0 << 4) | (t1 >>> 28); - t0 = s[2] ^ d2; - t1 = s[3] ^ d3; - bc4 = (t0 << 10) | (t1 >>> 22); - bc5 = (t1 << 10) | (t0 >>> 22); - t0 = s[34] ^ d4; - t1 = s[35] ^ d5; - bc6 = (t0 << 15) | (t1 >>> 17); - bc7 = (t1 << 15) | (t0 >>> 17); - t0 = s[16] ^ d6; - t1 = s[17] ^ d7; - bc8 = (t1 << 24) | (t0 >>> 8); - bc9 = (t0 << 24) | (t1 >>> 8); - t0 = s[48] ^ d8; - t1 = s[49] ^ d9; - bc0 = (t0 << 27) | (t1 >>> 5); - bc1 = (t1 << 27) | (t0 >>> 5); - s[20] = bc0 ^ (bc4 & ~bc2); - s[21] = bc1 ^ (bc5 & ~bc3); - s[2] = bc2 ^ (bc6 & ~bc4); - s[3] = bc3 ^ (bc7 & ~bc5); - s[34] = bc4 ^ (bc8 & ~bc6); - s[35] = bc5 ^ (bc9 & ~bc7); - s[16] = bc6 ^ (bc0 & ~bc8); - s[17] = bc7 ^ (bc1 & ~bc9); - s[48] = bc8 ^ (bc2 & ~bc0); - s[49] = bc9 ^ (bc3 & ~bc1); - - t0 = s[10] ^ d0; - t1 = s[11] ^ d1; - bc6 = (t1 << 9) | (t0 >>> 23); - bc7 = (t0 << 9) | (t1 >>> 23); - t0 = s[42] ^ d2; - t1 = s[43] ^ d3; - bc8 = (t0 << 2) | (t1 >>> 30); - bc9 = (t1 << 2) | (t0 >>> 30); - t0 = s[24] ^ d4; - t1 = s[25] ^ d5; - bc0 = (t1 << 30) | (t0 >>> 2); - bc1 = (t0 << 30) | (t1 >>> 2); - t0 = s[6] ^ d6; - t1 = s[7] ^ d7; - bc2 = (t1 << 23) | (t0 >>> 9); - bc3 = (t0 << 23) | (t1 >>> 9); - t0 = s[38] ^ d8; - t1 = s[39] ^ d9; - bc4 = (t1 << 7) | (t0 >>> 25); - bc5 = (t0 << 7) | (t1 >>> 25); - s[10] = bc0 ^ (bc4 & ~bc2); - s[11] = bc1 ^ (bc5 & ~bc3); - s[42] = bc2 ^ (bc6 & ~bc4); - s[43] = bc3 ^ (bc7 & ~bc5); - s[24] = bc4 ^ (bc8 & ~bc6); - s[25] = bc5 ^ (bc9 & ~bc7); - s[6] = bc6 ^ (bc0 & ~bc8); - s[7] = bc7 ^ (bc1 & ~bc9); - s[38] = bc8 ^ (bc2 & ~bc0); - s[39] = bc9 ^ (bc3 & ~bc1); - - // Round 3 - bc0 = s[0] ^ s[10] ^ s[20] ^ s[30] ^ s[40]; - bc1 = s[1] ^ s[11] ^ s[21] ^ s[31] ^ s[41]; - bc2 = s[2] ^ s[12] ^ s[22] ^ s[32] ^ s[42]; - bc3 = s[3] ^ s[13] ^ s[23] ^ s[33] ^ s[43]; - bc4 = s[4] ^ s[14] ^ s[24] ^ s[34] ^ s[44]; - bc5 = s[5] ^ s[15] ^ s[25] ^ s[35] ^ s[45]; - bc6 = s[6] ^ s[16] ^ s[26] ^ s[36] ^ s[46]; - bc7 = s[7] ^ s[17] ^ s[27] ^ s[37] ^ s[47]; - bc8 = s[8] ^ s[18] ^ s[28] ^ s[38] ^ s[48]; - bc9 = s[9] ^ s[19] ^ s[29] ^ s[39] ^ s[49]; - - d0 = bc8 ^ ((bc2 << 1) | (bc3 >>> 31)); - d1 = bc9 ^ ((bc3 << 1) | (bc2 >>> 31)); - d2 = bc0 ^ ((bc4 << 1) | (bc5 >>> 31)); - d3 = bc1 ^ ((bc5 << 1) | (bc4 >>> 31)); - d4 = bc2 ^ ((bc6 << 1) | (bc7 >>> 31)); - d5 = bc3 ^ ((bc7 << 1) | (bc6 >>> 31)); - d6 = bc4 ^ ((bc8 << 1) | (bc9 >>> 31)); - d7 = bc5 ^ ((bc9 << 1) | (bc8 >>> 31)); - d8 = bc6 ^ ((bc0 << 1) | (bc1 >>> 31)); - d9 = bc7 ^ ((bc1 << 1) | (bc0 >>> 31)); - - bc0 = s[0] ^ d0; - bc1 = s[1] ^ d1; - t0 = s[22] ^ d2; - t1 = s[23] ^ d3; - bc2 = (t1 << 12) | (t0 >>> 20); - bc3 = (t0 << 12) | (t1 >>> 20); - t0 = s[44] ^ d4; - t1 = s[45] ^ d5; - bc4 = (t1 << 11) | (t0 >>> 21); - bc5 = (t0 << 11) | (t1 >>> 21); - t0 = s[16] ^ d6; - t1 = s[17] ^ d7; - bc6 = (t0 << 21) | (t1 >>> 11); - bc7 = (t1 << 21) | (t0 >>> 11); - t0 = s[38] ^ d8; - t1 = s[39] ^ d9; - bc8 = (t0 << 14) | (t1 >>> 18); - bc9 = (t1 << 14) | (t0 >>> 18); - s[0] = bc0 ^ (bc4 & ~bc2) ^ KECCAK_RC[n + 4]; - s[1] = bc1 ^ (bc5 & ~bc3) ^ KECCAK_RC[n + 5]; - s[22] = bc2 ^ (bc6 & ~bc4); - s[23] = bc3 ^ (bc7 & ~bc5); - s[44] = bc4 ^ (bc8 & ~bc6); - s[45] = bc5 ^ (bc9 & ~bc7); - s[16] = bc6 ^ (bc0 & ~bc8); - s[17] = bc7 ^ (bc1 & ~bc9); - s[38] = bc8 ^ (bc2 & ~bc0); - s[39] = bc9 ^ (bc3 & ~bc1); - - t0 = s[30] ^ d0; - t1 = s[31] ^ d1; - bc4 = (t0 << 3) | (t1 >>> 29); - bc5 = (t1 << 3) | (t0 >>> 29); - t0 = s[2] ^ d2; - t1 = s[3] ^ d3; - bc6 = (t1 << 13) | (t0 >>> 19); - bc7 = (t0 << 13) | (t1 >>> 19); - t0 = s[24] ^ d4; - t1 = s[25] ^ d5; - bc8 = (t1 << 29) | (t0 >>> 3); - bc9 = (t0 << 29) | (t1 >>> 3); - t0 = s[46] ^ d6; - t1 = s[47] ^ d7; - bc0 = (t0 << 28) | (t1 >>> 4); - bc1 = (t1 << 28) | (t0 >>> 4); - t0 = s[18] ^ d8; - t1 = s[19] ^ d9; - bc2 = (t0 << 20) | (t1 >>> 12); - bc3 = (t1 << 20) | (t0 >>> 12); - s[30] = bc0 ^ (bc4 & ~bc2); - s[31] = bc1 ^ (bc5 & ~bc3); - s[2] = bc2 ^ (bc6 & ~bc4); - s[3] = bc3 ^ (bc7 & ~bc5); - s[24] = bc4 ^ (bc8 & ~bc6); - s[25] = bc5 ^ (bc9 & ~bc7); - s[46] = bc6 ^ (bc0 & ~bc8); - s[47] = bc7 ^ (bc1 & ~bc9); - s[18] = bc8 ^ (bc2 & ~bc0); - s[19] = bc9 ^ (bc3 & ~bc1); - - t0 = s[10] ^ d0; - t1 = s[11] ^ d1; - bc8 = (t0 << 18) | (t1 >>> 14); - bc9 = (t1 << 18) | (t0 >>> 14); - t0 = s[32] ^ d2; - t1 = s[33] ^ d3; - bc0 = (t0 << 1) | (t1 >>> 31); - bc1 = (t1 << 1) | (t0 >>> 31); - t0 = s[4] ^ d4; - t1 = s[5] ^ d5; - bc2 = (t0 << 6) | (t1 >>> 26); - bc3 = (t1 << 6) | (t0 >>> 26); - t0 = s[26] ^ d6; - t1 = s[27] ^ d7; - bc4 = (t0 << 25) | (t1 >>> 7); - bc5 = (t1 << 25) | (t0 >>> 7); - t0 = s[48] ^ d8; - t1 = s[49] ^ d9; - bc6 = (t0 << 8) | (t1 >>> 24); - bc7 = (t1 << 8) | (t0 >>> 24); - s[10] = bc0 ^ (bc4 & ~bc2); - s[11] = bc1 ^ (bc5 & ~bc3); - s[32] = bc2 ^ (bc6 & ~bc4); - s[33] = bc3 ^ (bc7 & ~bc5); - s[4] = bc4 ^ (bc8 & ~bc6); - s[5] = bc5 ^ (bc9 & ~bc7); - s[26] = bc6 ^ (bc0 & ~bc8); - s[27] = bc7 ^ (bc1 & ~bc9); - s[48] = bc8 ^ (bc2 & ~bc0); - s[49] = bc9 ^ (bc3 & ~bc1); - - t0 = s[40] ^ d0; - t1 = s[41] ^ d1; - bc2 = (t1 << 4) | (t0 >>> 28); - bc3 = (t0 << 4) | (t1 >>> 28); - t0 = s[12] ^ d2; - t1 = s[13] ^ d3; - bc4 = (t0 << 10) | (t1 >>> 22); - bc5 = (t1 << 10) | (t0 >>> 22); - t0 = s[34] ^ d4; - t1 = s[35] ^ d5; - bc6 = (t0 << 15) | (t1 >>> 17); - bc7 = (t1 << 15) | (t0 >>> 17); - t0 = s[6] ^ d6; - t1 = s[7] ^ d7; - bc8 = (t1 << 24) | (t0 >>> 8); - bc9 = (t0 << 24) | (t1 >>> 8); - t0 = s[28] ^ d8; - t1 = s[29] ^ d9; - bc0 = (t0 << 27) | (t1 >>> 5); - bc1 = (t1 << 27) | (t0 >>> 5); - s[40] = bc0 ^ (bc4 & ~bc2); - s[41] = bc1 ^ (bc5 & ~bc3); - s[12] = bc2 ^ (bc6 & ~bc4); - s[13] = bc3 ^ (bc7 & ~bc5); - s[34] = bc4 ^ (bc8 & ~bc6); - s[35] = bc5 ^ (bc9 & ~bc7); - s[6] = bc6 ^ (bc0 & ~bc8); - s[7] = bc7 ^ (bc1 & ~bc9); - s[28] = bc8 ^ (bc2 & ~bc0); - s[29] = bc9 ^ (bc3 & ~bc1); - - t0 = s[20] ^ d0; - t1 = s[21] ^ d1; - bc6 = (t1 << 9) | (t0 >>> 23); - bc7 = (t0 << 9) | (t1 >>> 23); - t0 = s[42] ^ d2; - t1 = s[43] ^ d3; - bc8 = (t0 << 2) | (t1 >>> 30); - bc9 = (t1 << 2) | (t0 >>> 30); - t0 = s[14] ^ d4; - t1 = s[15] ^ d5; - bc0 = (t1 << 30) | (t0 >>> 2); - bc1 = (t0 << 30) | (t1 >>> 2); - t0 = s[36] ^ d6; - t1 = s[37] ^ d7; - bc2 = (t1 << 23) | (t0 >>> 9); - bc3 = (t0 << 23) | (t1 >>> 9); - t0 = s[8] ^ d8; - t1 = s[9] ^ d9; - bc4 = (t1 << 7) | (t0 >>> 25); - bc5 = (t0 << 7) | (t1 >>> 25); - s[20] = bc0 ^ (bc4 & ~bc2); - s[21] = bc1 ^ (bc5 & ~bc3); - s[42] = bc2 ^ (bc6 & ~bc4); - s[43] = bc3 ^ (bc7 & ~bc5); - s[14] = bc4 ^ (bc8 & ~bc6); - s[15] = bc5 ^ (bc9 & ~bc7); - s[36] = bc6 ^ (bc0 & ~bc8); - s[37] = bc7 ^ (bc1 & ~bc9); - s[8] = bc8 ^ (bc2 & ~bc0); - s[9] = bc9 ^ (bc3 & ~bc1); - - // Round 4 - bc0 = s[0] ^ s[10] ^ s[20] ^ s[30] ^ s[40]; - bc1 = s[1] ^ s[11] ^ s[21] ^ s[31] ^ s[41]; - bc2 = s[2] ^ s[12] ^ s[22] ^ s[32] ^ s[42]; - bc3 = s[3] ^ s[13] ^ s[23] ^ s[33] ^ s[43]; - bc4 = s[4] ^ s[14] ^ s[24] ^ s[34] ^ s[44]; - bc5 = s[5] ^ s[15] ^ s[25] ^ s[35] ^ s[45]; - bc6 = s[6] ^ s[16] ^ s[26] ^ s[36] ^ s[46]; - bc7 = s[7] ^ s[17] ^ s[27] ^ s[37] ^ s[47]; - bc8 = s[8] ^ s[18] ^ s[28] ^ s[38] ^ s[48]; - bc9 = s[9] ^ s[19] ^ s[29] ^ s[39] ^ s[49]; - - d0 = bc8 ^ ((bc2 << 1) | (bc3 >>> 31)); - d1 = bc9 ^ ((bc3 << 1) | (bc2 >>> 31)); - d2 = bc0 ^ ((bc4 << 1) | (bc5 >>> 31)); - d3 = bc1 ^ ((bc5 << 1) | (bc4 >>> 31)); - d4 = bc2 ^ ((bc6 << 1) | (bc7 >>> 31)); - d5 = bc3 ^ ((bc7 << 1) | (bc6 >>> 31)); - d6 = bc4 ^ ((bc8 << 1) | (bc9 >>> 31)); - d7 = bc5 ^ ((bc9 << 1) | (bc8 >>> 31)); - d8 = bc6 ^ ((bc0 << 1) | (bc1 >>> 31)); - d9 = bc7 ^ ((bc1 << 1) | (bc0 >>> 31)); - - bc0 = s[0] ^ d0; - bc1 = s[1] ^ d1; - t0 = s[2] ^ d2; - t1 = s[3] ^ d3; - bc2 = (t1 << 12) | (t0 >>> 20); - bc3 = (t0 << 12) | (t1 >>> 20); - t0 = s[4] ^ d4; - t1 = s[5] ^ d5; - bc4 = (t1 << 11) | (t0 >>> 21); - bc5 = (t0 << 11) | (t1 >>> 21); - t0 = s[6] ^ d6; - t1 = s[7] ^ d7; - bc6 = (t0 << 21) | (t1 >>> 11); - bc7 = (t1 << 21) | (t0 >>> 11); - t0 = s[8] ^ d8; - t1 = s[9] ^ d9; - bc8 = (t0 << 14) | (t1 >>> 18); - bc9 = (t1 << 14) | (t0 >>> 18); - s[0] = bc0 ^ (bc4 & ~bc2) ^ KECCAK_RC[n + 6]; - s[1] = bc1 ^ (bc5 & ~bc3) ^ KECCAK_RC[n + 7]; - s[2] = bc2 ^ (bc6 & ~bc4); - s[3] = bc3 ^ (bc7 & ~bc5); - s[4] = bc4 ^ (bc8 & ~bc6); - s[5] = bc5 ^ (bc9 & ~bc7); - s[6] = bc6 ^ (bc0 & ~bc8); - s[7] = bc7 ^ (bc1 & ~bc9); - s[8] = bc8 ^ (bc2 & ~bc0); - s[9] = bc9 ^ (bc3 & ~bc1); - - t0 = s[10] ^ d0; - t1 = s[11] ^ d1; - bc4 = (t0 << 3) | (t1 >>> 29); - bc5 = (t1 << 3) | (t0 >>> 29); - t0 = s[12] ^ d2; - t1 = s[13] ^ d3; - bc6 = (t1 << 13) | (t0 >>> 19); - bc7 = (t0 << 13) | (t1 >>> 19); - t0 = s[14] ^ d4; - t1 = s[15] ^ d5; - bc8 = (t1 << 29) | (t0 >>> 3); - bc9 = (t0 << 29) | (t1 >>> 3); - t0 = s[16] ^ d6; - t1 = s[17] ^ d7; - bc0 = (t0 << 28) | (t1 >>> 4); - bc1 = (t1 << 28) | (t0 >>> 4); - t0 = s[18] ^ d8; - t1 = s[19] ^ d9; - bc2 = (t0 << 20) | (t1 >>> 12); - bc3 = (t1 << 20) | (t0 >>> 12); - s[10] = bc0 ^ (bc4 & ~bc2); - s[11] = bc1 ^ (bc5 & ~bc3); - s[12] = bc2 ^ (bc6 & ~bc4); - s[13] = bc3 ^ (bc7 & ~bc5); - s[14] = bc4 ^ (bc8 & ~bc6); - s[15] = bc5 ^ (bc9 & ~bc7); - s[16] = bc6 ^ (bc0 & ~bc8); - s[17] = bc7 ^ (bc1 & ~bc9); - s[18] = bc8 ^ (bc2 & ~bc0); - s[19] = bc9 ^ (bc3 & ~bc1); - - t0 = s[20] ^ d0; - t1 = s[21] ^ d1; - bc8 = (t0 << 18) | (t1 >>> 14); - bc9 = (t1 << 18) | (t0 >>> 14); - t0 = s[22] ^ d2; - t1 = s[23] ^ d3; - bc0 = (t0 << 1) | (t1 >>> 31); - bc1 = (t1 << 1) | (t0 >>> 31); - t0 = s[24] ^ d4; - t1 = s[25] ^ d5; - bc2 = (t0 << 6) | (t1 >>> 26); - bc3 = (t1 << 6) | (t0 >>> 26); - t0 = s[26] ^ d6; - t1 = s[27] ^ d7; - bc4 = (t0 << 25) | (t1 >>> 7); - bc5 = (t1 << 25) | (t0 >>> 7); - t0 = s[28] ^ d8; - t1 = s[29] ^ d9; - bc6 = (t0 << 8) | (t1 >>> 24); - bc7 = (t1 << 8) | (t0 >>> 24); - s[20] = bc0 ^ (bc4 & ~bc2); - s[21] = bc1 ^ (bc5 & ~bc3); - s[22] = bc2 ^ (bc6 & ~bc4); - s[23] = bc3 ^ (bc7 & ~bc5); - s[24] = bc4 ^ (bc8 & ~bc6); - s[25] = bc5 ^ (bc9 & ~bc7); - s[26] = bc6 ^ (bc0 & ~bc8); - s[27] = bc7 ^ (bc1 & ~bc9); - s[28] = bc8 ^ (bc2 & ~bc0); - s[29] = bc9 ^ (bc3 & ~bc1); - - t0 = s[30] ^ d0; - t1 = s[31] ^ d1; - bc2 = (t1 << 4) | (t0 >>> 28); - bc3 = (t0 << 4) | (t1 >>> 28); - t0 = s[32] ^ d2; - t1 = s[33] ^ d3; - bc4 = (t0 << 10) | (t1 >>> 22); - bc5 = (t1 << 10) | (t0 >>> 22); - t0 = s[34] ^ d4; - t1 = s[35] ^ d5; - bc6 = (t0 << 15) | (t1 >>> 17); - bc7 = (t1 << 15) | (t0 >>> 17); - t0 = s[36] ^ d6; - t1 = s[37] ^ d7; - bc8 = (t1 << 24) | (t0 >>> 8); - bc9 = (t0 << 24) | (t1 >>> 8); - t0 = s[38] ^ d8; - t1 = s[39] ^ d9; - bc0 = (t0 << 27) | (t1 >>> 5); - bc1 = (t1 << 27) | (t0 >>> 5); - s[30] = bc0 ^ (bc4 & ~bc2); - s[31] = bc1 ^ (bc5 & ~bc3); - s[32] = bc2 ^ (bc6 & ~bc4); - s[33] = bc3 ^ (bc7 & ~bc5); - s[34] = bc4 ^ (bc8 & ~bc6); - s[35] = bc5 ^ (bc9 & ~bc7); - s[36] = bc6 ^ (bc0 & ~bc8); - s[37] = bc7 ^ (bc1 & ~bc9); - s[38] = bc8 ^ (bc2 & ~bc0); - s[39] = bc9 ^ (bc3 & ~bc1); - - t0 = s[40] ^ d0; - t1 = s[41] ^ d1; - bc6 = (t1 << 9) | (t0 >>> 23); - bc7 = (t0 << 9) | (t1 >>> 23); - t0 = s[42] ^ d2; - t1 = s[43] ^ d3; - bc8 = (t0 << 2) | (t1 >>> 30); - bc9 = (t1 << 2) | (t0 >>> 30); - t0 = s[44] ^ d4; - t1 = s[45] ^ d5; - bc0 = (t1 << 30) | (t0 >>> 2); - bc1 = (t0 << 30) | (t1 >>> 2); - t0 = s[46] ^ d6; - t1 = s[47] ^ d7; - bc2 = (t1 << 23) | (t0 >>> 9); - bc3 = (t0 << 23) | (t1 >>> 9); - t0 = s[48] ^ d8; - t1 = s[49] ^ d9; - bc4 = (t1 << 7) | (t0 >>> 25); - bc5 = (t0 << 7) | (t1 >>> 25); - s[40] = bc0 ^ (bc4 & ~bc2); - s[41] = bc1 ^ (bc5 & ~bc3); - s[42] = bc2 ^ (bc6 & ~bc4); - s[43] = bc3 ^ (bc7 & ~bc5); - s[44] = bc4 ^ (bc8 & ~bc6); - s[45] = bc5 ^ (bc9 & ~bc7); - s[46] = bc6 ^ (bc0 & ~bc8); - s[47] = bc7 ^ (bc1 & ~bc9); - s[48] = bc8 ^ (bc2 & ~bc0); - s[49] = bc9 ^ (bc3 & ~bc1); - } -} diff --git a/std/hash/_sha3/sha3.ts b/std/hash/_sha3/sha3.ts deleted file mode 100644 index 2966ce2a4..000000000 --- a/std/hash/_sha3/sha3.ts +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -import { Sponge } from "./sponge.ts"; -import { keccakf } from "./keccakf.ts"; - -/** Sha3-224 hash */ -// deno-lint-ignore camelcase -export class Sha3_224 extends Sponge { - constructor() { - super({ - bitsize: 224, - rate: 144, - dsbyte: 6, - permutator: keccakf, - }); - } -} - -/** Sha3-256 hash */ -// deno-lint-ignore camelcase -export class Sha3_256 extends Sponge { - constructor() { - super({ - bitsize: 256, - rate: 136, - dsbyte: 6, - permutator: keccakf, - }); - } -} - -/** Sha3-384 hash */ -// deno-lint-ignore camelcase -export class Sha3_384 extends Sponge { - constructor() { - super({ - bitsize: 384, - rate: 104, - dsbyte: 6, - permutator: keccakf, - }); - } -} - -/** Sha3-512 hash */ -// deno-lint-ignore camelcase -export class Sha3_512 extends Sponge { - constructor() { - super({ - bitsize: 512, - rate: 72, - dsbyte: 6, - permutator: keccakf, - }); - } -} diff --git a/std/hash/_sha3/shake.ts b/std/hash/_sha3/shake.ts deleted file mode 100644 index 4fe24d7cf..000000000 --- a/std/hash/_sha3/shake.ts +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -import { Sponge } from "./sponge.ts"; -import { keccakf } from "./keccakf.ts"; - -/** Shake128 hash */ -export class Shake128 extends Sponge { - /** - * Instantiates a new Shake128 hash - * @param bitsize length of hash in bits - */ - constructor(bitsize: number) { - if (bitsize < 8) { - throw new Error("shake128: `bitsize` too small"); - } - - if (bitsize % 8 !== 0) { - throw new Error("shake128: `bitsize` must be multiple of 8"); - } - - super({ - bitsize: bitsize, - rate: 168, - dsbyte: 0x1f, - permutator: keccakf, - }); - } -} - -/** - * Instantiates a new Shake256 hash - * @param bitsize length of hash in bits - */ -export class Shake256 extends Sponge { - constructor(bitsize: number) { - if (bitsize < 8) { - throw new Error("shake256: `bitsize` too small"); - } - - if (bitsize % 8 !== 0) { - throw new Error("shake256: `bitsize` must be multiple of 8"); - } - - super({ - bitsize: bitsize, - rate: 136, - dsbyte: 0x1f, - permutator: keccakf, - }); - } -} diff --git a/std/hash/_sha3/sponge.ts b/std/hash/_sha3/sponge.ts deleted file mode 100644 index 9ad67ca07..000000000 --- a/std/hash/_sha3/sponge.ts +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -import * as hex from "../../encoding/hex.ts"; - -type SpongePermutator = (data: Uint8Array) => void; - -/** Sponge construction option */ -export interface SpongeOption { - bitsize: number; - rate: number; - dsbyte: number; - permutator: SpongePermutator; -} - -export type Message = string | ArrayBuffer; - -const STATE_SIZE = 200; -const TYPE_ERROR_MSG = "sha3: `data` is invalid type"; - -/** Sponge construction */ -export class Sponge { - #option: SpongeOption; - #state: Uint8Array; - #rp: number; - #absorbing: boolean; - - constructor(option: SpongeOption) { - this.#option = option; - this.#state = new Uint8Array(STATE_SIZE); - this.#rp = 0; - this.#absorbing = true; - } - - /** Applies padding to internal state */ - private pad(): void { - this.#state[this.#rp] ^= this.#option.dsbyte; - this.#state[this.#option.rate - 1] ^= 0x80; - } - - /** Squeezes internal state */ - protected squeeze(length: number): Uint8Array { - if (length < 0) { - throw new Error("sha3: length cannot be negative"); - } - - this.pad(); - - const hash = new Uint8Array(length); - let pos = 0; - while (length > 0) { - const r = length > this.#option.rate ? this.#option.rate : length; - this.#option.permutator(this.#state); - hash.set(this.#state.slice(0, r), pos); - length -= r; - pos += r; - } - - this.#absorbing = false; - return hash; - } - - /** Updates internal state by absorbing */ - update(data: Message): this { - if (!this.#absorbing) { - throw new Error("sha3: cannot update already finalized hash"); - } - - let msg: Uint8Array; - - if (typeof data === "string") { - msg = new TextEncoder().encode(data as string); - } else if (typeof data === "object") { - if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) { - msg = new Uint8Array(data); - } else { - throw new Error(TYPE_ERROR_MSG); - } - } else { - throw new Error(TYPE_ERROR_MSG); - } - - let rp = this.#rp; - - for (let i = 0; i < msg.length; ++i) { - this.#state[rp++] ^= msg[i]; - if (rp >= this.#option.rate) { - this.#option.permutator(this.#state); - rp = 0; - } - } - - this.#rp = rp; - return this; - } - - /** Returns the hash in ArrayBuffer */ - digest(): ArrayBuffer { - return this.squeeze(this.#option.bitsize >> 3); - } - - /** Returns the hash in given format */ - toString(format: "hex" = "hex"): string { - const rawOutput = this.squeeze(this.#option.bitsize >> 3); - switch (format) { - case "hex": - return hex.encodeToString(rawOutput); - default: - throw new Error("sha3: invalid output format"); - } - } -} diff --git a/std/hash/_wasm/Cargo.lock b/std/hash/_wasm/Cargo.lock deleted file mode 100644 index 5ff47d756..000000000 --- a/std/hash/_wasm/Cargo.lock +++ /dev/null @@ -1,291 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "block-padding", - "generic-array", -] - -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - -[[package]] -name = "bumpalo" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - -[[package]] -name = "cpuid-bool" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" - -[[package]] -name = "deno-hash" -version = "0.1.0" -dependencies = [ - "digest", - "md-5", - "md2", - "md4", - "ripemd160", - "ripemd320", - "sha-1", - "sha2", - "sha3", - "wasm-bindgen", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "generic-array" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "keccak" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "log" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "md-5" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5a279bb9607f9f53c22d496eade00d138d1bdcccd07d74650387cf94942a15" -dependencies = [ - "block-buffer", - "digest", - "opaque-debug", -] - -[[package]] -name = "md2" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfd23bb613adebff88451d962b449f93e2ca5d97400021ad5895740778d95f78" -dependencies = [ - "block-buffer", - "digest", - "opaque-debug", -] - -[[package]] -name = "md4" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd1a7931601ee6a560262a1dc9a8369949f5b7ae20b2bbf029c74fbd6d1b09e2" -dependencies = [ - "block-buffer", - "digest", - "opaque-debug", -] - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "proc-macro2" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "quote" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "ripemd160" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" -dependencies = [ - "block-buffer", - "digest", - "opaque-debug", -] - -[[package]] -name = "ripemd320" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ff9fb4227f99b2078691fbd1bf16edd94041f15b02a3c7b4a155d0074954191" -dependencies = [ - "block-buffer", - "digest", - "opaque-debug", -] - -[[package]] -name = "sha-1" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "170a36ea86c864a3f16dd2687712dd6646f7019f301e57537c7f4dc9f5916770" -dependencies = [ - "block-buffer", - "cfg-if", - "cpuid-bool", - "digest", - "opaque-debug", -] - -[[package]] -name = "sha2" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2933378ddfeda7ea26f48c555bdad8bb446bf8a3d17832dc83e380d444cfb8c1" -dependencies = [ - "block-buffer", - "cfg-if", - "cpuid-bool", - "digest", - "opaque-debug", -] - -[[package]] -name = "sha3" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" -dependencies = [ - "block-buffer", - "digest", - "keccak", - "opaque-debug", -] - -[[package]] -name = "syn" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5304cfdf27365b7585c25d4af91b35016ed21ef88f17ced89c7093b43dba8b6" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "typenum" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" - -[[package]] -name = "unicode-xid" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" - -[[package]] -name = "version_check" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" - -[[package]] -name = "wasm-bindgen" -version = "0.2.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f22b422e2a757c35a73774860af8e112bff612ce6cb604224e8e47641a9e4f68" -dependencies = [ - "bumpalo", - "lazy_static", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b13312a745c08c469f0b292dd2fcd6411dba5f7160f593da6ef69b64e407038" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307" diff --git a/std/hash/_wasm/Cargo.toml b/std/hash/_wasm/Cargo.toml deleted file mode 100644 index 7a9119552..000000000 --- a/std/hash/_wasm/Cargo.toml +++ /dev/null @@ -1,29 +0,0 @@ -[package] -name = "deno-hash" -version = "0.1.0" -authors = ["the Deno authors"] -edition = "2018" -license = "MIT" -repository = "https://github.com/denoland/deno" - -[lib] -crate-type = ["cdylib"] - -[dependencies] -digest = "0.9.0" -md2 = "0.9.0" -md4 = "0.9.0" -md-5 = "0.9.1" -ripemd160 = "0.9.1" -ripemd320 = "0.9.0" -sha-1 = "0.9.1" -sha2 = "0.9.1" -sha3 = "0.9.1" -wasm-bindgen = "0.2.68" - -[profile.release] -lto = true -opt-level = 3 - -[package.metadata.wasm-pack.profile.release] -wasm-opt = ["-O", "--enable-mutable-globals"] diff --git a/std/hash/_wasm/README.md b/std/hash/_wasm/README.md deleted file mode 100644 index 721e496d2..000000000 --- a/std/hash/_wasm/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# How to build - -## Prerequisite - -`wasm-pack` is required. - -```sh -cargo install wasm-pack -``` - -## Build - -```sh -deno run --allow-read --allow-write --allow-run ./build.ts -``` - -`wasm.js` will be generated. diff --git a/std/hash/_wasm/build.ts b/std/hash/_wasm/build.ts deleted file mode 100644 index a328c2615..000000000 --- a/std/hash/_wasm/build.ts +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -import { encode as base64Encode } from "../../encoding/base64.ts"; - -// 1. build wasm -async function buildWasm(path: string): Promise<void> { - const cmd = [ - "wasm-pack", - "build", - "--target", - "web", - "--release", - "-d", - path, - ]; - const builder = Deno.run({ cmd }); - const status = await builder.status(); - - if (!status.success) { - console.error(`Failed to build wasm: ${status.code}`); - Deno.exit(1); - } -} - -// 2. encode wasm -async function encodeWasm(wasmPath: string): Promise<string> { - const wasm = await Deno.readFile(`${wasmPath}/deno_hash_bg.wasm`); - return base64Encode(wasm); -} - -// 3. generate script -async function generate(wasm: string, output: string): Promise<void> { - const initScript = await Deno.readTextFile(`${output}/deno_hash.js`); - const denoHashScript = - "// deno-lint-ignore-file\n" + - "//deno-fmt-ignore-file\n" + - "//deno-lint-ignore-file\n" + - `import * as base64 from "../../encoding/base64.ts";` + - `export const source = base64.decode("${wasm}");` + - initScript; - - await Deno.writeFile("wasm.js", new TextEncoder().encode(denoHashScript)); -} - -const OUTPUT_DIR = "./out"; - -await buildWasm(OUTPUT_DIR); -const wasm = await encodeWasm(OUTPUT_DIR); -await generate(wasm, OUTPUT_DIR); diff --git a/std/hash/_wasm/hash.ts b/std/hash/_wasm/hash.ts deleted file mode 100644 index eb6636dab..000000000 --- a/std/hash/_wasm/hash.ts +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -import init, { - source, - create_hash as createHash, - update_hash as updateHash, - digest_hash as digestHash, - DenoHash, -} from "./wasm.js"; - -import * as hex from "../../encoding/hex.ts"; -import * as base64 from "../../encoding/base64.ts"; -import type { Hasher, Message, OutputFormat } from "../hasher.ts"; - -await init(source); - -const TYPE_ERROR_MSG = "hash: `data` is invalid type"; - -export class Hash implements Hasher { - #hash: DenoHash; - #digested: boolean; - - constructor(algorithm: string) { - this.#hash = createHash(algorithm); - this.#digested = false; - } - - /** - * Update internal state - * @param data data to update - */ - update(data: Message): this { - let msg: Uint8Array; - - if (typeof data === "string") { - msg = new TextEncoder().encode(data as string); - } else if (typeof data === "object") { - if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) { - msg = new Uint8Array(data); - } else { - throw new Error(TYPE_ERROR_MSG); - } - } else { - throw new Error(TYPE_ERROR_MSG); - } - - updateHash(this.#hash, msg); - - return this; - } - - /** Returns final hash */ - digest(): ArrayBuffer { - if (this.#digested) throw new Error("hash: already digested"); - - this.#digested = true; - return digestHash(this.#hash); - } - - /** - * Returns hash as a string of given format - * @param format format of output string (hex or base64). Default is hex - */ - toString(format: OutputFormat = "hex"): string { - const finalized = new Uint8Array(this.digest()); - - switch (format) { - case "hex": - return hex.encodeToString(finalized); - case "base64": - return base64.encode(finalized); - default: - throw new Error("hash: invalid format"); - } - } -} diff --git a/std/hash/_wasm/src/lib.rs b/std/hash/_wasm/src/lib.rs deleted file mode 100644 index 7e72a7471..000000000 --- a/std/hash/_wasm/src/lib.rs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -use digest::{Digest, DynDigest}; -use wasm_bindgen::prelude::*; - -#[wasm_bindgen] -pub struct DenoHash { - inner: Box<dyn DynDigest>, -} - -#[wasm_bindgen] -pub fn create_hash(algorithm: &str) -> Result<DenoHash, JsValue> { - let hash: Option<Box<dyn DynDigest>> = match algorithm { - "md2" => Some(Box::new(md2::Md2::new())), - "md4" => Some(Box::new(md4::Md4::new())), - "md5" => Some(Box::new(md5::Md5::new())), - "ripemd160" => Some(Box::new(ripemd160::Ripemd160::new())), - "ripemd320" => Some(Box::new(ripemd320::Ripemd320::new())), - "sha1" => Some(Box::new(sha1::Sha1::new())), - "sha224" => Some(Box::new(sha2::Sha224::new())), - "sha256" => Some(Box::new(sha2::Sha256::new())), - "sha384" => Some(Box::new(sha2::Sha384::new())), - "sha512" => Some(Box::new(sha2::Sha512::new())), - "sha3-224" => Some(Box::new(sha3::Sha3_224::new())), - "sha3-256" => Some(Box::new(sha3::Sha3_256::new())), - "sha3-384" => Some(Box::new(sha3::Sha3_384::new())), - "sha3-512" => Some(Box::new(sha3::Sha3_512::new())), - "keccak224" => Some(Box::new(sha3::Keccak224::new())), - "keccak256" => Some(Box::new(sha3::Keccak256::new())), - "keccak384" => Some(Box::new(sha3::Keccak384::new())), - "keccak512" => Some(Box::new(sha3::Keccak512::new())), - _ => None, - }; - - if let Some(h) = hash { - Ok(DenoHash { inner: h }) - } else { - let err_msg = format!("unsupported hash algorithm: {}", algorithm); - Err(JsValue::from_str(&err_msg)) - } -} - -#[wasm_bindgen] -pub fn update_hash(hash: &mut DenoHash, data: &[u8]) { - hash.inner.update(data) -} - -#[wasm_bindgen] -pub fn digest_hash(hash: &mut DenoHash) -> Box<[u8]> { - hash.inner.finalize_reset() -} diff --git a/std/hash/_wasm/wasm.js b/std/hash/_wasm/wasm.js deleted file mode 100644 index 9f4adbd02..000000000 --- a/std/hash/_wasm/wasm.js +++ /dev/null @@ -1,254 +0,0 @@ -// deno-lint-ignore-file -//deno-fmt-ignore-file -//deno-lint-ignore-file -import * as base64 from "../../encoding/base64.ts";export const source = base64.decode("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HiADIAJBmAFqQcgBEIsBIgRBADYCyAEgBEHMAWogAkEIakHIABCLARpB/IXAACEEQQAMEQsgAEHYgcAARwRAIAAoAABB89CFiwNHDRALIAJBkgRqQgA3AQAgAkGaBGpBADsBACACQZwEakIANwIAIAJBpARqQgA3AgAgAkGsBGpCADcCACACQbQEakIANwIAIAJBvARqQgA3AgAgAkHEBGpBADoAACACQcUEakEANgAAIAJByQRqQQA7AAAgAkHLBGpBADoAACACQcAANgKIBCACQQA7AYwEIAJBADYBjgQgAkGYAWogAkGIBGpBxAAQiwEaIAJBqANqIgQgAkHUAWopAgA3AwAgAkGgA2oiBSACQcwBaikCADcDACACQZgDaiIJIAJBxAFqKQIANwMAIAJBkANqIgogAkG8AWopAgA3AwAgAkGIA2oiBiACQbQBaikCADcDACACQYADaiIHIAJBrAFqKQIANwMAIAJB+AJqIgggAkGkAWopAgA3AwAgAiACKQKcATcD8AJB4ABBCBChASIDRQ0XIANCADcDACADQQA2AhwgAyACKQPwAjcDICADQfiXwAApAwA3AwggA0EQakGAmMAAKQMANwMAIANBGGpBiJjAACgCADYCACADQShqIAgpAwA3AwAgA0EwaiAHKQMANwMAIANBOGogBikDADcDACADQUBrIAopAwA3AwAgA0HIAGogCSkDADcDACADQdAAaiAFKQMANwMAIANB2ABqIAQpAwA3AwBB3IHAACEEQQAMEAsgAEGAgsAARg0FIABBgILAAEEGEIMBRQ0FIABBrILAAEYNBiAAQayCwABBBhCDAUUNBiAAQdiCwABGDQcgAEHYgsAAQQYQgwFFDQcgAEGEg8AARwRAIABBhIPAAEEGEIMBDQ8LIAJBADYCiAQgAkGIBGpBBHIhBEEAIQMDQCADIARqQQA6AAAgAiACKAKIBEEBajYCiAQgA0EBaiIDQYABRw0ACyACQZgBaiACQYgEakGEARCLARogAkHwAmogAkGYAWpBBHJBgAEQiwEaQdgBQQgQoQEiA0UNGCADQgA3AwggA0IANwMAIANBADYCUCADQZCZwAApAwA3AxAgA0EYakGYmcAAKQMANwMAIANBIGpBoJnAACkDADcDACADQShqQaiZwAApAwA3AwAgA0EwakGwmcAAKQMANwMAIANBOGpBuJnAACkDADcDACADQUBrQcCZwAApAwA3AwAgA0HIAGpByJnAACkDADcDACADQdQAaiACQfACakGAARCLARpBjIPAACEEQQAMDwsgAEGwg8AARg0HIAApAABC89CFm9PFjJk0UQ0HIABB3IPAAEYNCCAAKQAAQvPQhZvTxcyaNlENCCAAQYiEwABGDQkgACkAAELz0IWb0+WMnDRRDQkgAEG0hMAARwRAIAApAABC89CFm9OlzZgyUg0OCyACQZgBakEAQcgBEJEBGiACQf4CakIANwEAIAJBhgNqQgA3AQAgAkGOA2pCADcBACACQZYDakIANwEAIAJBngNqQgA3AQAgAkGmA2pCADcBACACQa4DakIANwEAIAJBtgNqQQA2AQAgAkG6A2pBADsBACACQQA7AfQCIAJCADcB9gIgAkHIADYC8AIgAkGIBGogAkHwAmpBzAAQiwEaIAJBCGogAkGIBGpBBHJByAAQiwEaQZgCQQgQoQEiA0UNGyADIAJBmAFqQcgBEIsBIgRBADYCyAEgBEHMAWogAkEIakHIABCLARpBvITAACEEQQAMDgsgAkGSBGpCADcBACACQZoEakEAOwEAIAJBEDYCiAQgAkEAOwGMBCACQQA2AY4EIAJBqAFqIgMgAkGYBGoiBCgCADYCACACQaABaiIJIAJBkARqIgUpAwA3AwAgAkHoAmoiBiACQaQBaikCADcDACACIAIpA4gENwOYASACIAIpApwBNwPgAiACQcABaiIHQgA3AwAgAkG4AWoiCEIANwMAIAJBsAFqIg1CADcDACADQgA3AwAgCUIANwMAIAJCADcDmAEgAkH6AmpCADcBACACQYIDakEAOwEAIAJBEDYC8AIgAkEAOwH0AiACQQA2AfYCIAQgAkGAA2ooAgA2AgAgBSACQfgCaiIKKQMANwMAIAJBEGoiCyACQZQEaikCADcDACACIAIpA/ACNwOIBCACIAIpAowENwMIIAJB0AFqIgwgCykDADcDACACIAIpAwg3A8gBIAogBikDADcDACACIAIpA+ACNwPwAiACQcAEaiIGIAwpAwA3AwAgAkG4BGoiCyACKQPIATcDACACQbAEaiIMIAcpAwA3AwAgAkGoBGoiByAIKQMANwMAIAJBoARqIgggDSkDADcDACAEIAMpAwA3AwAgBSAJKQMANwMAIAIgAikDmAE3A4gEQdQAQQQQoQEiA0UNDiADQQA2AgAgAyACKQPwAjcCBCADIAIpA4gENwIUIANBDGogCikDADcCACADQRxqIAUpAwA3AgAgA0EkaiAEKQMANwIAIANBLGogCCkDADcCACADQTRqIAcpAwA3AgAgA0E8aiAMKQMANwIAIANBxABqIAspAwA3AgAgA0HMAGogBikDADcCAEGEgMAAIQRBAAwNCyACQZIEakIANwEAIAJBmgRqQQA7AQAgAkGcBGpCADcCACACQaQEakIANwIAIAJBrARqQgA3AgAgAkG0BGpCADcCACACQbwEakIANwIAIAJBxARqQQA6AAAgAkHFBGpBADYAACACQckEakEAOwAAIAJBywRqQQA6AAAgAkHAADYCiAQgAkEAOwGMBCACQQA2AY4EIAJBmAFqIAJBiARqQcQAEIsBGiACQagDaiIEIAJB1AFqKQIANwMAIAJBoANqIgUgAkHMAWopAgA3AwAgAkGYA2oiCSACQcQBaikCADcDACACQZADaiIKIAJBvAFqKQIANwMAIAJBiANqIgYgAkG0AWopAgA3AwAgAkGAA2oiByACQawBaikCADcDACACQfgCaiIIIAJBpAFqKQIANwMAIAIgAikCnAE3A/ACQeAAQQgQoQEiA0UNEyADQQA2AgggA0IANwMAIAMgAikD8AI3AgwgA0EUaiAIKQMANwIAIANBHGogBykDADcCACADQSRqIAYpAwA3AgAgA0EsaiAKKQMANwIAIANBNGogCSkDADcCACADQTxqIAUpAwA3AgAgA0HEAGogBCkDADcCACADQdQAakHIl8AAKQIANwIAIANBwJfAACkCADcCTEGsgMAAIQRBAAwMCyACQZIEakIANwEAIAJBmgRqQQA7AQAgAkGcBGpCADcCACACQaQEakIANwIAIAJBrARqQgA3AgAgAkG0BGpCADcCACACQbwEakIANwIAIAJBxARqQQA6AAAgAkHFBGpBADYAACACQckEakEAOwAAIAJBywRqQQA6AAAgAkHAADYCiAQgAkEAOwGMBCACQQA2AY4EIAJBmAFqIAJBiARqQcQAEIsBGiACQagDaiIEIAJB1AFqKQIANwMAIAJBoANqIgUgAkHMAWopAgA3AwAgAkGYA2oiCSACQcQBaikCADcDACACQZADaiIKIAJBvAFqKQIANwMAIAJBiANqIgYgAkG0AWopAgA3AwAgAkGAA2oiByACQawBaikCADcDACACQfgCaiIIIAJBpAFqKQIANwMAIAIgAikCnAE3A/ACQeAAQQgQoQEiA0UNEiADQgA3AwAgA0EANgIcIAMgAikD8AI3AyAgA0H4l8AAKQMANwMIIANBEGpBgJjAACkDADcDACADQRhqQYiYwAAoAgA2AgAgA0EoaiAIKQMANwMAIANBMGogBykDADcDACADQThqIAYpAwA3AwAgA0FAayAKKQMANwMAIANByABqIAkpAwA3AwAgA0HQAGogBSkDADcDACADQdgAaiAEKQMANwMAQYSBwAAhBEEADAsLIAJBkgRqQgA3AQAgAkGaBGpBADsBACACQZwEakIANwIAIAJBpARqQgA3AgAgAkGsBGpCADcCACACQbQEakIANwIAIAJBvARqQgA3AgAgAkHEBGpBADoAACACQcUEakEANgAAIAJByQRqQQA7AAAgAkHLBGpBADoAACACQcAANgKIBCACQQA7AYwEIAJBADYBjgQgAkGYAWogAkGIBGpBxAAQiwEaIAJBqANqIgQgAkHUAWopAgA3AwAgAkGgA2oiBSACQcwBaikCADcDACACQZgDaiIJIAJBxAFqKQIANwMAIAJBkANqIgogAkG8AWopAgA3AwAgAkGIA2oiBiACQbQBaikCADcDACACQYADaiIHIAJBrAFqKQIANwMAIAJB+AJqIgggAkGkAWopAgA3AwAgAiACKQKcATcD8AJB+ABBCBChASIDRQ0MIANCADcDACADQQA2AjAgAyACKQPwAjcCNCADQdCXwAApAwA3AwggA0EQakHYl8AAKQMANwMAIANBGGpB4JfAACkDADcDACADQSBqQeiXwAApAwA3AwAgA0EoakHwl8AAKQMANwMAIANBPGogCCkDADcCACADQcQAaiAHKQMANwIAIANBzABqIAYpAwA3AgAgA0HUAGogCikDADcCACADQdwAaiAJKQMANwIAIANB5ABqIAUpAwA3AgAgA0HsAGogBCkDADcCAEG0gcAAIQRBAAwKCyACQZIEakIANwEAIAJBmgRqQQA7AQAgAkGcBGpCADcCACACQaQEakIANwIAIAJBrARqQgA3AgAgAkG0BGpCADcCACACQbwEakIANwIAIAJBxARqQQA6AAAgAkHFBGpBADYAACACQckEakEAOwAAIAJBywRqQQA6AAAgAkHAADYCiAQgAkEAOwGMBCACQQA2AY4EIAJBmAFqIAJBiARqQcQAEIsBGiACQagDaiIEIAJB1AFqKQIANwMAIAJBoANqIgUgAkHMAWopAgA3AwAgAkGYA2oiCSACQcQBaikCADcDACACQZADaiIKIAJBvAFqKQIANwMAIAJBiANqIgYgAkG0AWopAgA3AwAgAkGAA2oiByACQawBaikCADcDACACQfgCaiIIIAJBpAFqKQIANwMAIAIgAikCnAE3A/ACQfAAQQgQoQEiA0UNESADQQA2AgggA0IANwMAIAMgAikD8AI3AgwgA0EUaiAIKQMANwIAIANBHGogBykDADcCACADQSRqIAYpAwA3AgAgA0EsaiAKKQMANwIAIANBNGogCSkDADcCACADQTxqIAUpAwA3AgAgA0HEAGogBCkDADcCACADQeQAakGkmMAAKQIANwIAIANB3ABqQZyYwAApAgA3AgAgA0HUAGpBlJjAACkCADcCACADQYyYwAApAgA3AkxBiILAACEEQQAMCQsgAkGSBGpCADcBACACQZoEakEAOwEAIAJBnARqQgA3AgAgAkGkBGpCADcCACACQawEakIANwIAIAJBtARqQgA3AgAgAkG8BGpCADcCACACQcQEakEAOgAAIAJBxQRqQQA2AAAgAkHJBGpBADsAACACQcsEakEAOgAAIAJBwAA2AogEIAJBADsBjAQgAkEANgGOBCACQZgBaiACQYgEakHEABCLARogAkGoA2oiBCACQdQBaikCADcDACACQaADaiIFIAJBzAFqKQIANwMAIAJBmANqIgkgAkHEAWopAgA3AwAgAkGQA2oiCiACQbwBaikCADcDACACQYgDaiIGIAJBtAFqKQIANwMAIAJBgANqIgcgAkGsAWopAgA3AwAgAkH4AmoiCCACQaQBaikCADcDACACIAIpApwBNwPwAkHwAEEIEKEBIgNFDRAgA0EANgIIIANCADcDACADIAIpA/ACNwIMIANBFGogCCkDADcCACADQRxqIAcpAwA3AgAgA0EkaiAGKQMANwIAIANBLGogCikDADcCACADQTRqIAkpAwA3AgAgA0E8aiAFKQMANwIAIANBxABqIAQpAwA3AgAgA0HkAGpBxJjAACkCADcCACADQdwAakG8mMAAKQIANwIAIANB1ABqQbSYwAApAgA3AgAgA0GsmMAAKQIANwJMQbSCwAAhBEEADAgLIAJBADYCiAQgAkGIBGpBBHIhBEEAIQMDQCADIARqQQA6AAAgAiACKAKIBEEBajYCiAQgA0EBaiIDQYABRw0ACyACQZgBaiACQYgEakGEARCLARogAkHwAmogAkGYAWpBBHJBgAEQiwEaQdgBQQgQoQEiA0UNECADQgA3AwggA0IANwMAIANBADYCUCADQdCYwAApAwA3AxAgA0EYakHYmMAAKQMANwMAIANBIGpB4JjAACkDADcDACADQShqQeiYwAApAwA3AwAgA0EwakHwmMAAKQMANwMAIANBOGpB+JjAACkDADcDACADQUBrQYCZwAApAwA3AwAgA0HIAGpBiJnAACkDADcDACADQdQAaiACQfACakGAARCLARpB4ILAACEEQQAMBwsgAkGYAWpBAEHIARCRARogAkEANgLwAkEEIQMDQCACQfACaiADakEAOgAAIAIgAigC8AJBAWo2AvACIANBAWoiA0GUAUcNAAsgAkGIBGogAkHwAmpBlAEQiwEaIAJBCGogAkGIBGpBBHJBkAEQiwEaQeACQQgQoQEiA0UNECADIAJBmAFqQcgBEIsBIgRBADYCyAEgBEHMAWogAkEIakGQARCLARpBuIPAACEEQQAMBgsgAkGYAWpBAEHIARCRARogAkEANgLwAkEEIQMDQCACQfACaiADakEAOgAAIAIgAigC8AJBAWo2AvACIANBAWoiA0GMAUcNAAsgAkGIBGogAkHwAmpBjAEQiwEaIAJBCGogAkGIBGpBBHJBiAEQiwEaQdgCQQgQoQEiA0UNECADIAJBmAFqQcgBEIsBIgRBADYCyAEgBEHMAWogAkEIakGIARCLARpB5IPAACEEQQAMBQsgAkGYAWpBAEHIARCRARogAkEANgLwAkEEIQMDQCACQfACaiADakEAOgAAIAIgAigC8AJBAWo2AvACIANBAWoiA0HsAEcNAAsgAkGIBGogAkHwAmpB7AAQiwEaIAJBCGogAkGIBGpBBHJB6AAQiwEaQbgCQQgQoQEiA0UNECADIAJBmAFqQcgBEIsBIgRBADYCyAEgBEHMAWogAkEIakHoABCLARpBkITAACEEQQAMBAsgAkGYAWpBAEHIARCRARogAkEANgLwAkEEIQMDQCACQfACaiADakEAOgAAIAIgAigC8AJBAWo2AvACIANBAWoiA0GUAUcNAAsgAkGIBGogAkHwAmpBlAEQiwEaIAJBCGogAkGIBGpBBHJBkAEQiwEaQeACQQgQoQEiA0UNDSADIAJBmAFqQcgBEIsBIgRBADYCyAEgBEHMAWogAkEIakGQARCLARpB7ITAACEEQQAMAwsgAkGYAWpBAEHIARCRARogAkEANgLwAkEEIQMDQCACQfACaiADakEAOgAAIAIgAigC8AJBAWo2AvACIANBAWoiA0GMAUcNAAsgAkGIBGogAkHwAmpBjAEQiwEaIAJBCGogAkGIBGpBBHJBiAEQiwEaQdgCQQgQoQEiA0UNDSADIAJBmAFqQcgBEIsBIgRBADYCyAEgBEHMAWogAkEIakGIARCLARpBnIXAACEEQQAMAgsgAkGYAWpBAEHIARCRARogAkEANgLwAkEEIQMDQCACQfACaiADakEAOgAAIAIgAigC8AJBAWo2AvACIANBAWoiA0HsAEcNAAsgAkGIBGogAkHwAmpB7AAQiwEaIAJBCGogAkGIBGpBBHJB6AAQiwEaQbgCQQgQoQEiA0UNDSADIAJBmAFqQcgBEIsBIgRBADYCyAEgBEHMAWogAkEIakHoABCLARpBzIXAACEEQQAMAQsgAkEBNgL0AiACIAI2AvACQThBARChASIDRQ0DIAJCODcCjAQgAiADNgKIBCACIAJBiARqNgIIIAJBrAFqQQE2AgAgAkIBNwKcASACQbyGwAA2ApgBIAIgAkHwAmo2AqgBIAJBCGogAkGYAWoQFg0EIAIoAogEIAIoApAEEAAhAyACKAKMBARAIAIoAogEEBALQQELIAEEQCAAEBALDQRBDEEEEKEBIgBFDQUgACAENgIIIAAgAzYCBCAAQQA2AgAgAkGgBWokACAADwtB1ABBBEG0pcAAKAIAIgBBAiAAGxEAAAALQfgAQQhBtKXAACgCACIAQQIgABsRAAAAC0E4QQFBtKXAACgCACIAQQIgABsRAAAAC0GYh8AAQTMgAkGYAWpBzIfAAEHch8AAEHkACyADEAIAC0EMQQRBtKXAACgCACIAQQIgABsRAAAAC0HgAEEIQbSlwAAoAgAiAEECIAAbEQAAAAtB8ABBCEG0pcAAKAIAIgBBAiAAGxEAAAALQdgBQQhBtKXAACgCACIAQQIgABsRAAAAC0HgAkEIQbSlwAAoAgAiAEECIAAbEQAAAAtB2AJBCEG0pcAAKAIAIgBBAiAAGxEAAAALQbgCQQhBtKXAACgCACIAQQIgABsRAAAAC0GYAkEIQbSlwAAoAgAiAEECIAAbEQAAAAuJLgEifyMAQUBqIgxBGGoiFUIANwMAIAxBIGoiD0IANwMAIAxBOGoiFkIANwMAIAxBMGoiEEIANwMAIAxBKGoiF0IANwMAIAxBCGoiCSABKQAINwMAIAxBEGoiFCABKQAQNwMAIBUgASgAGCIVNgIAIA8gASgAICIPNgIAIAwgASkAADcDACAMIAEoABwiEjYCHCAMIAEoACQiGTYCJCAXIAEoACgiFzYCACAMIAEoACwiGzYCLCAQIAEoADAiEDYCACAMIAEoADQiHDYCNCAWIAEoADgiFjYCACAMIAEoADwiATYCPCAAIBYgDyABIBkgDCgCACIYIBQoAgAiFCAYIBsgDCgCDCIdIAwoAgQiHiABIBggASAXIAwoAhQiDCAAKAIQIgQgGCAAKAIAIiMgACgCDCITIAAoAggiBSAAKAIEIgZzc2pqQQt3aiIDQQp3IgJqIB0gBUEKdyIFaiAEIB5qIAUgBnMgA3NqQQ53IBNqIgQgAnMgEyAJKAIAIhNqIAMgBkEKdyIGcyAEc2pBD3cgBWoiA3NqQQx3IAZqIgUgA0EKdyIJcyAGIBRqIAMgBEEKdyIGcyAFc2pBBXcgAmoiA3NqQQh3IAZqIgJBCnciBGogDyAFQQp3IgVqIAYgFWogAyAFcyACc2pBB3cgCWoiBiAEcyAJIBJqIAIgA0EKdyIDcyAGc2pBCXcgBWoiAnNqQQt3IANqIgUgAkEKdyIJcyADIBlqIAIgBkEKdyIGcyAFc2pBDXcgBGoiA3NqQQ53IAZqIgJBCnciBGogHCAFQQp3IgVqIAYgG2ogAyAFcyACc2pBD3cgCWoiBiAEcyAJIBBqIAIgA0EKdyIDcyAGc2pBBncgBWoiAnNqQQd3IANqIgkgAkEKdyINcyADIBZqIAIgBkEKdyIKcyAJc2pBCXcgBGoiB3NqQQh3IApqIgVBCnciBmogBiASIB0gFSAZIAAoAhgiA0EKdyICaiACIBggACgCHCIOQQp3IgRqIBIgACgCICIIaiAIIBYgACgCJCILaiAMIAAoAhRqIA4gCEF/c3IgA3NqQeaXioUFakEIdyALaiIIIAMgBEF/c3JzakHml4qFBWpBCXdqIgMgCCACQX9zcnNqQeaXioUFakEJdyAEaiICIAMgCEEKdyIEQX9zcnNqQeaXioUFakELd2oiCCACIANBCnciA0F/c3JzakHml4qFBWpBDXcgBGoiDkEKdyILaiAcIAhBCnciEWogFCACQQp3IgJqIAMgG2ogBCATaiAOIAggAkF/c3JzakHml4qFBWpBD3cgA2oiAyAOIBFBf3Nyc2pB5peKhQVqQQ93IAJqIgIgAyALQX9zcnNqQeaXioUFakEFdyARaiIEIAIgA0EKdyIDQX9zcnNqQeaXioUFakEHdyALaiIIIAQgAkEKdyICQX9zcnNqQeaXioUFakEHdyADaiIOQQp3IgtqIBcgCEEKdyIRaiAeIARBCnciBGogAiAPaiABIANqIA4gCCAEQX9zcnNqQeaXioUFakEIdyACaiIDIA4gEUF/c3JzakHml4qFBWpBC3cgBGoiAiADIAtBf3Nyc2pB5peKhQVqQQ53IBFqIgQgAiADQQp3IghBf3Nyc2pB5peKhQVqQQ53IAtqIg4gBCACQQp3IgtBf3Nyc2pB5peKhQVqQQx3IAhqIhFBCnciA2ogAyAdIA5BCnciAmogAiAbIARBCnciGmogCyAVaiARIAJBf3NxIAIgBXFyakGkorfiBWpBCXcgGmoiAiADcSAFIANBf3NxcmpBpKK34gVqQQ13aiIDIAZxIAIgBkF/c3FyakGkorfiBWpBD3dqIgQgAkEKdyIGcSADIAZBf3NxcmpBpKK34gVqQQd3aiIfIANBCnciA3EgBCADQX9zcXJqQaSit+IFakEMdyAGaiIgQQp3IgJqIBYgH0EKdyIFaiAXIARBCnciBGogAyAMaiAGIBxqIAQgIHEgHyAEQX9zcXJqQaSit+IFakEIdyADaiIGIAVxICAgBUF/c3FyakGkorfiBWpBCXcgBGoiAyACcSAGIAJBf3NxcmpBpKK34gVqQQt3IAVqIgQgBkEKdyIGcSADIAZBf3NxcmpBpKK34gVqQQd3IAJqIh8gA0EKdyIDcSAEIANBf3NxcmpBpKK34gVqQQd3IAZqIiBBCnciAmogGSAfQQp3IgVqIBQgBEEKdyIEaiADIBBqIAYgD2ogBCAgcSAfIARBf3NxcmpBpKK34gVqQQx3IANqIgYgBXEgICAFQX9zcXJqQaSit+IFakEHdyAEaiIDIAJxIAYgAkF/c3FyakGkorfiBWpBBncgBWoiHyAGQQp3IgZxIAMgBkF/c3FyakGkorfiBWpBD3cgAmoiICADQQp3IgNxIB8gA0F/c3FyakGkorfiBWpBDXcgBmoiIUEKdyIiaiAeIBYgECAeIAdBCnciBGogBCAcIAlBCnciBWogBSANIBRqIAogEmogCCAQaiARIA4gGkF/c3JzakHml4qFBWpBBncgC2oiAiAHcSAFIAJBf3NxcmpBmfOJ1AVqQQd3IA1qIgUgAnEgBCAFQX9zcXJqQZnzidQFakEGd2oiBCAFcSACQQp3IgkgBEF/c3FyakGZ84nUBWpBCHdqIgIgBHEgBUEKdyINIAJBf3NxcmpBmfOJ1AVqQQ13IAlqIgVBCnciCmogHSACQQp3IgdqIAEgBEEKdyIEaiANIBVqIAkgF2ogAiAFcSAEIAVBf3NxcmpBmfOJ1AVqQQt3IA1qIgIgBXEgByACQX9zcXJqQZnzidQFakEJdyAEaiIFIAJxIAogBUF/c3FyakGZ84nUBWpBB3cgB2oiBCAFcSACQQp3IgkgBEF/c3FyakGZ84nUBWpBD3cgCmoiAiAEcSAFQQp3Ig0gAkF/c3FyakGZ84nUBWpBB3cgCWoiBUEKdyIKaiATIAJBCnciB2ogDCAEQQp3IgRqIA0gGWogCSAYaiACIAVxIAQgBUF/c3FyakGZ84nUBWpBDHcgDWoiAiAFcSAHIAJBf3NxcmpBmfOJ1AVqQQ93IARqIgUgAnEgCiAFQX9zcXJqQZnzidQFakEJdyAHaiIEIAVxIAJBCnciDSAEQX9zcXJqQZnzidQFakELdyAKaiICIARxIAVBCnciCiACQX9zcXJqQZnzidQFakEHdyANaiIFQQp3IgdqIAwgH0EKdyIJaiABIANqIAYgE2ogCSAhcSAgIAlBf3NxcmpBpKK34gVqQQt3IANqIgYgIUF/c3IgB3NqQfP9wOsGakEJdyAJaiIDIAZBf3NyICJzakHz/cDrBmpBB3cgB2oiCSADQX9zciAGQQp3IgZzakHz/cDrBmpBD3cgImoiByAJQX9zciADQQp3IgNzakHz/cDrBmpBC3cgBmoiCEEKdyIOaiAZIAdBCnciC2ogFSAJQQp3IglqIAMgFmogBiASaiAIIAdBf3NyIAlzakHz/cDrBmpBCHcgA2oiBiAIQX9zciALc2pB8/3A6wZqQQZ3IAlqIgMgBkF/c3IgDnNqQfP9wOsGakEGdyALaiIJIANBf3NyIAZBCnciBnNqQfP9wOsGakEOdyAOaiIHIAlBf3NyIANBCnciA3NqQfP9wOsGakEMdyAGaiIIQQp3Ig5qIBcgB0EKdyILaiATIAlBCnciCWogAyAQaiAGIA9qIAggB0F/c3IgCXNqQfP9wOsGakENdyADaiIGIAhBf3NyIAtzakHz/cDrBmpBBXcgCWoiAyAGQX9zciAOc2pB8/3A6wZqQQ53IAtqIgkgA0F/c3IgBkEKdyIGc2pB8/3A6wZqQQ13IA5qIgcgCUF/c3IgA0EKdyIDc2pB8/3A6wZqQQ13IAZqIghBCnciDmogFSAHQQp3IgtqIA8gFSAPIBcgAkEKdyIRaiAdIARBCnciBGogIEEKdyIaIAQgCiAPaiANIBtqIAIgBXEgBCAFQX9zcXJqQZnzidQFakENdyAKaiICIAVxIBEgAkF/cyIEcXJqQZnzidQFakEMd2oiBSAEcnNqQaHX5/YGakELdyARaiIEIAVBf3NyIAJBCnciAnNqQaHX5/YGakENdyAaaiINQQp3IgpqIAEgBEEKdyIRaiAZIAVBCnciBWogAiAUaiAWIBpqIA0gBEF/c3IgBXNqQaHX5/YGakEGdyACaiICIA1Bf3NyIBFzakGh1+f2BmpBB3cgBWoiBSACQX9zciAKc2pBodfn9gZqQQ53IBFqIgQgBUF/c3IgAkEKdyICc2pBodfn9gZqQQl3IApqIg0gBEF/c3IgBUEKdyIFc2pBodfn9gZqQQ13IAJqIgpBCnciEWogGCANQQp3IhpqIBIgBEEKdyIEaiAFIBNqIAIgHmogCiANQX9zciAEc2pBodfn9gZqQQ93IAVqIgIgCkF/c3IgGnNqQaHX5/YGakEOdyAEaiIFIAJBf3NyIBFzakGh1+f2BmpBCHcgGmoiBCAFQX9zciACQQp3Ig1zakGh1+f2BmpBDXcgEWoiCiAEQX9zciAFQQp3IgVzakGh1+f2BmpBBncgDWoiEUEKdyIaaiADIBxqIAYgFGogCUEKdyIJIAggB0F/c3JzakHz/cDrBmpBB3cgA2oiAiAIQX9zciALc2pB8/3A6wZqQQV3IAlqIgYgAnEgDiAGQX9zcXJqQenttdMHakEPdyALaiIDIAZxIAJBCnciByADQX9zcXJqQenttdMHakEFdyAOaiICIANxIAZBCnciCCACQX9zcXJqQenttdMHakEIdyAHaiIGQQp3Ig5qIAEgAkEKdyILaiAbIANBCnciA2ogCCAdaiAGIAcgHmogAiAGcSADIAZBf3NxcmpB6e210wdqQQt3IAhqIgZxIAsgBkF/c3FyakHp7bXTB2pBDncgA2oiAyAGcSAOIANBf3NxcmpB6e210wdqQQ53IAtqIgIgA3EgBkEKdyIHIAJBf3NxcmpB6e210wdqQQZ3IA5qIgYgAnEgA0EKdyIIIAZBf3NxcmpB6e210wdqQQ53IAdqIgNBCnciDmogHCAGQQp3IgtqIBMgAkEKdyICaiAIIBBqIAcgDGogAyAGcSACIANBf3NxcmpB6e210wdqQQZ3IAhqIgYgA3EgCyAGQX9zcXJqQenttdMHakEJdyACaiIDIAZxIA4gA0F/c3FyakHp7bXTB2pBDHcgC2oiAiADcSAGQQp3IgcgAkF/c3FyakHp7bXTB2pBCXcgDmoiBiACcSADQQp3IgggBkF/c3FyakHp7bXTB2pBDHcgB2oiA0EKdyIOaiAWIAJBCnciAmogCCAXaiADIAcgEmogAyAGcSACIANBf3NxcmpB6e210wdqQQV3IAhqIgNxIAZBCnciByADQX9zcXJqQenttdMHakEPdyACaiIGIANxIA4gBkF/c3FyakHp7bXTB2pBCHcgB2oiCCAVIB0gGCAQIApBCnciAmogAiAMIARBCnciBGogBSAbaiACIA0gHGogESAKQX9zciAEc2pBodfn9gZqQQV3IAVqIgIgEUF/c3JzakGh1+f2BmpBDHcgBGoiBCACQX9zciAac2pBodfn9gZqQQd3aiINIARBf3NyIAJBCnciCnNqQaHX5/YGakEFdyAaaiILQQp3IgJqIAIgFyANQQp3IgVqIAUgGyAEQQp3IgRqIAQgCiAZaiAJIB5qIAQgC3EgDSAEQX9zcXJqQdz57vh4akELdyAKaiIEIAVxIAsgBUF/c3FyakHc+e74eGpBDHdqIgUgAnEgBCACQX9zcXJqQdz57vh4akEOd2oiDSAEQQp3IgJxIAUgAkF/c3FyakHc+e74eGpBD3dqIgogBUEKdyIFcSANIAVBf3NxcmpB3Pnu+HhqQQ53IAJqIgtBCnciBGogHCAKQQp3IglqIBQgDUEKdyINaiAFIBBqIAIgD2ogCyANcSAKIA1Bf3NxcmpB3Pnu+HhqQQ93IAVqIgIgCXEgCyAJQX9zcXJqQdz57vh4akEJdyANaiIFIARxIAIgBEF/c3FyakHc+e74eGpBCHcgCWoiDSACQQp3IgJxIAUgAkF/c3FyakHc+e74eGpBCXcgBGoiCiAFQQp3IgVxIA0gBUF/c3FyakHc+e74eGpBDncgAmoiC0EKdyIEaiAEIAwgCkEKdyIJaiAWIA1BCnciDWogASAFaiACIBJqIAsgDXEgCiANQX9zcXJqQdz57vh4akEFdyAFaiICIAlxIAsgCUF/c3FyakHc+e74eGpBBncgDWoiBSAEcSACIARBf3NxcmpB3Pnu+HhqQQh3IAlqIgQgAkEKdyICcSAFIAJBf3NxcmpB3Pnu+HhqQQZ3aiIJIAVBCnciBXEgBCAFQX9zcXJqQdz57vh4akEFdyACaiINQQp3IgpzIAcgEGogA0EKdyIDIA1zIAhzakEIdyAOaiIHc2pBBXcgA2oiDkEKdyILaiAIQQp3IgggHmogAyAXaiAHIAhzIA5zakEMdyAKaiIDIAtzIAogFGogDiAHQQp3IgpzIANzakEJdyAIaiIHc2pBDHcgCmoiCCAHQQp3Ig5zIAogDGogByADQQp3IgNzIAhzakEFdyALaiIKc2pBDncgA2oiB0EKdyILaiAIQQp3IgggE2ogAyASaiAIIApzIAdzakEGdyAOaiIDIAtzIA4gFWogByAKQQp3IgpzIANzakEIdyAIaiIHc2pBDXcgCmoiCCAHQQp3Ig5zIAogHGogByADQQp3IgNzIAhzakEGdyALaiIKc2pBBXcgA2oiB0EKdyILIAAoAhRqNgIUIAAgAyAYaiAKIAhBCnciCHMgB3NqQQ93IA5qIhFBCnciGiAAKAIQajYCECAAIAAoAiAgDiAdaiAHIApBCnciCnMgEXNqQQ13IAhqIgdBCndqNgIgIAAgIyAPIBMgGCAEQQp3IgNqIAUgFGogAiATaiADIA1xIAkgA0F/c3FyakHc+e74eGpBDHcgBWoiGCAGIAlBCnciFEF/c3JzakHO+s/KempBCXcgA2oiAyAYIAZBCnciBkF/c3JzakHO+s/KempBD3cgFGoiAkEKdyIFaiAQIANBCnciE2ogEiAYQQp3IhBqIAYgGWogDCAUaiACIAMgEEF/c3JzakHO+s/KempBBXcgBmoiDCACIBNBf3Nyc2pBzvrPynpqQQt3IBBqIhIgDCAFQX9zcnNqQc76z8p6akEGdyATaiIQIBIgDEEKdyIMQX9zcnNqQc76z8p6akEIdyAFaiIYIBAgEkEKdyISQX9zcnNqQc76z8p6akENdyAMaiIUQQp3IhNqIB0gGEEKdyIPaiAPIB4gEEEKdyIQaiASIBZqIAwgF2ogFCAYIBBBf3Nyc2pBzvrPynpqQQx3IBJqIgwgFCAPQX9zcnNqQc76z8p6akEFdyAQaiIPIAwgE0F/c3JzakHO+s/KempBDHdqIhIgDyAMQQp3IgxBf3Nyc2pBzvrPynpqQQ13IBNqIhcgEiAPQQp3Ig9Bf3Nyc2pBzvrPynpqQQ53IAxqIhBBCnciFmo2AgAgACAIIBlqIAsgEXMgB3NqQQt3IApqIhkgACgCHGo2AhwgACAAKAIYIAogG2ogByAacyAZc2pBC3cgC2pqNgIYIAAgDCAbaiAQIBcgEkEKdyIMQX9zcnNqQc76z8p6akELdyAPaiISQQp3IhkgACgCJGo2AiQgACAAKAIMIA8gFWogEiAQIBdBCnciFUF/c3JzakHO+s/KempBCHcgDGoiD0EKd2o2AgwgACABIAxqIA8gEiAWQX9zcnNqQc76z8p6akEFdyAVaiIBIAAoAghqNgIIIAAgACgCBCAVIBxqIAEgDyAZQX9zcnNqQc76z8p6akEGdyAWamo2AgQLqi0BIH8jAEFAaiIPQRhqIhVCADcDACAPQSBqIg1CADcDACAPQThqIhNCADcDACAPQTBqIhBCADcDACAPQShqIhFCADcDACAPQQhqIhggASkACDcDACAPQRBqIhQgASkAEDcDACAVIAEoABgiFTYCACANIAEoACAiDTYCACAPIAEpAAA3AwAgDyABKAAcIhI2AhwgDyABKAAkIho2AiQgESABKAAoIhE2AgAgDyABKAAsIhs2AiwgECABKAAwIhA2AgAgDyABKAA0Ihw2AjQgEyABKAA4IhM2AgAgDyABKAA8IgE2AjwgACAbIBEgDygCFCIWIBYgHCARIBYgEiAaIA0gGiAVIBIgGyAVIA8oAgQiFyAAKAIQIh5qIAAoAggiH0EKdyIEIAAoAgQiHXMgDygCACIZIAAoAgAiICAAKAIMIgUgHSAfc3NqakELdyAeaiIDc2pBDncgBWoiAkEKdyIHaiAUKAIAIhQgHUEKdyIGaiAYKAIAIhggBWogAyAGcyACc2pBD3cgBGoiCCAHcyAPKAIMIg8gBGogAiADQQp3IgNzIAhzakEMdyAGaiICc2pBBXcgA2oiCSACQQp3IgpzIAMgFmogAiAIQQp3IgNzIAlzakEIdyAHaiICc2pBB3cgA2oiB0EKdyIIaiAaIAlBCnciCWogAyASaiACIAlzIAdzakEJdyAKaiIDIAhzIAogDWogByACQQp3IgJzIANzakELdyAJaiIHc2pBDXcgAmoiCSAHQQp3IgpzIAIgEWogByADQQp3IgNzIAlzakEOdyAIaiICc2pBD3cgA2oiB0EKdyIIaiAIIAEgAkEKdyILaiAKIBxqIAMgEGogAiAJQQp3IgNzIAdzakEGdyAKaiICIAcgC3NzakEHdyADaiIHIAJBCnciCXMgAyATaiACIAhzIAdzakEJdyALaiIIc2pBCHdqIgMgCHEgB0EKdyIHIANBf3NxcmpBmfOJ1AVqQQd3IAlqIgJBCnciCmogESADQQp3IgtqIBcgCEEKdyIIaiAHIBxqIAkgFGogAiADcSAIIAJBf3NxcmpBmfOJ1AVqQQZ3IAdqIgMgAnEgCyADQX9zcXJqQZnzidQFakEIdyAIaiICIANxIAogAkF/c3FyakGZ84nUBWpBDXcgC2oiByACcSADQQp3IgggB0F/c3FyakGZ84nUBWpBC3cgCmoiAyAHcSACQQp3IgkgA0F/c3FyakGZ84nUBWpBCXcgCGoiAkEKdyIKaiAZIANBCnciC2ogECAHQQp3IgdqIAkgD2ogASAIaiACIANxIAcgAkF/c3FyakGZ84nUBWpBB3cgCWoiAyACcSALIANBf3NxcmpBmfOJ1AVqQQ93IAdqIgIgA3EgCiACQX9zcXJqQZnzidQFakEHdyALaiIHIAJxIANBCnciCCAHQX9zcXJqQZnzidQFakEMdyAKaiIDIAdxIAJBCnciCSADQX9zcXJqQZnzidQFakEPdyAIaiICQQp3IgpqIBsgA0EKdyILaiATIAdBCnciB2ogCSAYaiAIIBZqIAIgA3EgByACQX9zcXJqQZnzidQFakEJdyAJaiIDIAJxIAsgA0F/c3FyakGZ84nUBWpBC3cgB2oiAiADcSAKIAJBf3NxcmpBmfOJ1AVqQQd3IAtqIgcgAnEgA0EKdyIDIAdBf3NxcmpBmfOJ1AVqQQ13IApqIgggB3EgAkEKdyICIAhBf3MiC3FyakGZ84nUBWpBDHcgA2oiCUEKdyIKaiAUIAhBCnciCGogEyAHQQp3IgdqIAIgEWogAyAPaiAJIAtyIAdzakGh1+f2BmpBC3cgAmoiAyAJQX9zciAIc2pBodfn9gZqQQ13IAdqIgIgA0F/c3IgCnNqQaHX5/YGakEGdyAIaiIHIAJBf3NyIANBCnciA3NqQaHX5/YGakEHdyAKaiIIIAdBf3NyIAJBCnciAnNqQaHX5/YGakEOdyADaiIJQQp3IgpqIBggCEEKdyILaiAXIAdBCnciB2ogAiANaiABIANqIAkgCEF/c3IgB3NqQaHX5/YGakEJdyACaiIDIAlBf3NyIAtzakGh1+f2BmpBDXcgB2oiAiADQX9zciAKc2pBodfn9gZqQQ93IAtqIgcgAkF/c3IgA0EKdyIDc2pBodfn9gZqQQ53IApqIgggB0F/c3IgAkEKdyICc2pBodfn9gZqQQh3IANqIglBCnciCmogGyAIQQp3IgtqIBwgB0EKdyIHaiACIBVqIAMgGWogCSAIQX9zciAHc2pBodfn9gZqQQ13IAJqIgMgCUF/c3IgC3NqQaHX5/YGakEGdyAHaiICIANBf3NyIApzakGh1+f2BmpBBXcgC2oiByACQX9zciADQQp3IghzakGh1+f2BmpBDHcgCmoiCSAHQX9zciACQQp3IgpzakGh1+f2BmpBB3cgCGoiC0EKdyIDaiADIBsgCUEKdyICaiACIBogB0EKdyIHaiAHIAogF2ogCCAQaiALIAlBf3NyIAdzakGh1+f2BmpBBXcgCmoiByACcSALIAJBf3NxcmpB3Pnu+HhqQQt3aiICIANxIAcgA0F/c3FyakHc+e74eGpBDHdqIgkgB0EKdyIDcSACIANBf3NxcmpB3Pnu+HhqQQ53aiIKIAJBCnciAnEgCSACQX9zcXJqQdz57vh4akEPdyADaiILQQp3IgdqIBQgCkEKdyIIaiAQIAlBCnciCWogAiANaiADIBlqIAkgC3EgCiAJQX9zcXJqQdz57vh4akEOdyACaiIDIAhxIAsgCEF/c3FyakHc+e74eGpBD3cgCWoiAiAHcSADIAdBf3NxcmpB3Pnu+HhqQQl3IAhqIgkgA0EKdyIDcSACIANBf3NxcmpB3Pnu+HhqQQh3IAdqIgogAkEKdyICcSAJIAJBf3NxcmpB3Pnu+HhqQQl3IANqIgtBCnciB2ogEyAKQQp3IghqIAEgCUEKdyIJaiACIBJqIAMgD2ogCSALcSAKIAlBf3NxcmpB3Pnu+HhqQQ53IAJqIgMgCHEgCyAIQX9zcXJqQdz57vh4akEFdyAJaiICIAdxIAMgB0F/c3FyakHc+e74eGpBBncgCGoiCCADQQp3IgNxIAIgA0F/c3FyakHc+e74eGpBCHcgB2oiCSACQQp3IgJxIAggAkF/c3FyakHc+e74eGpBBncgA2oiCkEKdyILaiAZIAlBCnciB2ogFCAIQQp3IghqIAIgGGogAyAVaiAIIApxIAkgCEF/c3FyakHc+e74eGpBBXcgAmoiAyAHcSAKIAdBf3NxcmpB3Pnu+HhqQQx3IAhqIgIgAyALQX9zcnNqQc76z8p6akEJdyAHaiIHIAIgA0EKdyIDQX9zcnNqQc76z8p6akEPdyALaiIIIAcgAkEKdyICQX9zcnNqQc76z8p6akEFdyADaiIJQQp3IgpqIBggCEEKdyILaiAQIAdBCnciB2ogAiASaiADIBpqIAkgCCAHQX9zcnNqQc76z8p6akELdyACaiIDIAkgC0F/c3JzakHO+s/KempBBncgB2oiAiADIApBf3Nyc2pBzvrPynpqQQh3IAtqIgcgAiADQQp3IgNBf3Nyc2pBzvrPynpqQQ13IApqIgggByACQQp3IgJBf3Nyc2pBzvrPynpqQQx3IANqIglBCnciCmogDSAIQQp3IgtqIA8gB0EKdyIHaiACIBdqIAMgE2ogCSAIIAdBf3Nyc2pBzvrPynpqQQV3IAJqIgMgCSALQX9zcnNqQc76z8p6akEMdyAHaiICIAMgCkF/c3JzakHO+s/KempBDXcgC2oiByACIANBCnciCEF/c3JzakHO+s/KempBDncgCmoiCSAHIAJBCnciCkF/c3JzakHO+s/KempBC3cgCGoiC0EKdyIhIAVqIBMgDSABIBogGSAUIBkgGyAPIBcgASAZIBAgASAYICAgHyAFQX9zciAdc2ogFmpB5peKhQVqQQh3IB5qIgNBCnciAmogBiAaaiAEIBlqIAUgEmogEyAeIAMgHSAEQX9zcnNqakHml4qFBWpBCXcgBWoiBSADIAZBf3Nyc2pB5peKhQVqQQl3IARqIgQgBSACQX9zcnNqQeaXioUFakELdyAGaiIGIAQgBUEKdyIFQX9zcnNqQeaXioUFakENdyACaiIDIAYgBEEKdyIEQX9zcnNqQeaXioUFakEPdyAFaiICQQp3IgxqIBUgA0EKdyIOaiAcIAZBCnciBmogBCAUaiAFIBtqIAIgAyAGQX9zcnNqQeaXioUFakEPdyAEaiIFIAIgDkF/c3JzakHml4qFBWpBBXcgBmoiBCAFIAxBf3Nyc2pB5peKhQVqQQd3IA5qIgYgBCAFQQp3IgVBf3Nyc2pB5peKhQVqQQd3IAxqIgMgBiAEQQp3IgRBf3Nyc2pB5peKhQVqQQh3IAVqIgJBCnciDGogDyADQQp3Ig5qIBEgBkEKdyIGaiAEIBdqIAUgDWogAiADIAZBf3Nyc2pB5peKhQVqQQt3IARqIgUgAiAOQX9zcnNqQeaXioUFakEOdyAGaiIEIAUgDEF/c3JzakHml4qFBWpBDncgDmoiBiAEIAVBCnciA0F/c3JzakHml4qFBWpBDHcgDGoiAiAGIARBCnciDEF/c3JzakHml4qFBWpBBncgA2oiDkEKdyIFaiAFIBIgAkEKdyIEaiAEIA8gBkEKdyIGaiAGIAwgG2ogAyAVaiAGIA5xIAIgBkF/c3FyakGkorfiBWpBCXcgDGoiBiAEcSAOIARBf3NxcmpBpKK34gVqQQ13aiIEIAVxIAYgBUF/c3FyakGkorfiBWpBD3dqIgIgBkEKdyIFcSAEIAVBf3NxcmpBpKK34gVqQQd3aiIMIARBCnciBHEgAiAEQX9zcXJqQaSit+IFakEMdyAFaiIOQQp3IgZqIBMgDEEKdyIDaiARIAJBCnciAmogBCAWaiAFIBxqIAIgDnEgDCACQX9zcXJqQaSit+IFakEIdyAEaiIFIANxIA4gA0F/c3FyakGkorfiBWpBCXcgAmoiBCAGcSAFIAZBf3NxcmpBpKK34gVqQQt3IANqIgIgBUEKdyIFcSAEIAVBf3NxcmpBpKK34gVqQQd3IAZqIgwgBEEKdyIEcSACIARBf3NxcmpBpKK34gVqQQd3IAVqIg5BCnciBmogBiAaIAxBCnciA2ogFCACQQp3IgJqIAQgEGogBSANaiACIA5xIAwgAkF/c3FyakGkorfiBWpBDHcgBGoiBSADcSAOIANBf3NxcmpBpKK34gVqQQd3IAJqIgQgBnEgBSAGQX9zcXJqQaSit+IFakEGdyADaiIGIAVBCnciBXEgBCAFQX9zcXJqQaSit+IFakEPd2oiAyAEQQp3IgRxIAYgBEF/c3FyakGkorfiBWpBDXcgBWoiAkEKdyIMaiAXIANBCnciDmogFiAGQQp3IgZqIAEgBGogBSAYaiACIAZxIAMgBkF/c3FyakGkorfiBWpBC3cgBGoiBSACQX9zciAOc2pB8/3A6wZqQQl3IAZqIgQgBUF/c3IgDHNqQfP9wOsGakEHdyAOaiIGIARBf3NyIAVBCnciBXNqQfP9wOsGakEPdyAMaiIDIAZBf3NyIARBCnciBHNqQfP9wOsGakELdyAFaiICQQp3IgxqIBogA0EKdyIOaiAVIAZBCnciBmogBCATaiAFIBJqIAIgA0F/c3IgBnNqQfP9wOsGakEIdyAEaiIFIAJBf3NyIA5zakHz/cDrBmpBBncgBmoiBCAFQX9zciAMc2pB8/3A6wZqQQZ3IA5qIgYgBEF/c3IgBUEKdyIFc2pB8/3A6wZqQQ53IAxqIgMgBkF/c3IgBEEKdyIEc2pB8/3A6wZqQQx3IAVqIgJBCnciDGogESADQQp3Ig5qIBggBkEKdyIGaiAEIBBqIAUgDWogAiADQX9zciAGc2pB8/3A6wZqQQ13IARqIgUgAkF/c3IgDnNqQfP9wOsGakEFdyAGaiIEIAVBf3NyIAxzakHz/cDrBmpBDncgDmoiBiAEQX9zciAFQQp3IgVzakHz/cDrBmpBDXcgDGoiAyAGQX9zciAEQQp3IgRzakHz/cDrBmpBDXcgBWoiAkEKdyIMaiAVIANBCnciDmogDSAGQQp3IgZqIAYgBCAcaiAFIBRqIAIgA0F/c3IgBnNqQfP9wOsGakEHdyAEaiIGIAJBf3NyIA5zakHz/cDrBmpBBXdqIgUgBnEgDCAFQX9zcXJqQenttdMHakEPdyAOaiIEIAVxIAZBCnciAyAEQX9zcXJqQenttdMHakEFdyAMaiIGIARxIAVBCnciAiAGQX9zcXJqQenttdMHakEIdyADaiIFQQp3IgxqIAEgBkEKdyIOaiAbIARBCnciBGogAiAPaiAFIAMgF2ogBSAGcSAEIAVBf3NxcmpB6e210wdqQQt3IAJqIgVxIA4gBUF/c3FyakHp7bXTB2pBDncgBGoiBCAFcSAMIARBf3NxcmpB6e210wdqQQ53IA5qIgYgBHEgBUEKdyIDIAZBf3NxcmpB6e210wdqQQZ3IAxqIgUgBnEgBEEKdyICIAVBf3NxcmpB6e210wdqQQ53IANqIgRBCnciDGogHCAFQQp3Ig5qIBggBkEKdyIGaiACIBBqIAMgFmogBCAFcSAGIARBf3NxcmpB6e210wdqQQZ3IAJqIgUgBHEgDiAFQX9zcXJqQenttdMHakEJdyAGaiIEIAVxIAwgBEF/c3FyakHp7bXTB2pBDHcgDmoiBiAEcSAFQQp3IgMgBkF/c3FyakHp7bXTB2pBCXcgDGoiBSAGcSAEQQp3IgIgBUF/c3FyakHp7bXTB2pBDHcgA2oiBEEKdyIMaiATIAZBCnciBmogBiACIBFqIAQgAyASaiAEIAVxIAYgBEF/c3FyakHp7bXTB2pBBXcgAmoiBHEgBUEKdyIGIARBf3NxcmpB6e210wdqQQ93aiIFIARxIAwgBUF/c3FyakHp7bXTB2pBCHcgBmoiAyAFQQp3IgJzIAYgEGogBSAEQQp3IhBzIANzakEIdyAMaiIFc2pBBXcgEGoiBEEKdyIGaiADQQp3Ig0gF2ogECARaiAFIA1zIARzakEMdyACaiIRIAZzIA0gAiAUaiAEIAVBCnciDXMgEXNqQQl3aiIQc2pBDHcgDWoiFyAQQQp3IhRzIA0gFmogECARQQp3Ig1zIBdzakEFdyAGaiIRc2pBDncgDWoiEEEKdyIWaiAXQQp3IhMgGGogDSASaiARIBNzIBBzakEGdyAUaiINIBZzIBQgFWogECARQQp3IhJzIA1zakEIdyATaiIRc2pBDXcgEmoiECARQQp3IhNzIBIgHGogESANQQp3Ig1zIBBzakEGdyAWaiISc2pBBXcgDWoiEUEKdyIWajYCCCAAIA0gGWogEiAQQQp3Ig1zIBFzakEPdyATaiIQQQp3IhkgHyAIIBVqIAsgCSAHQQp3IhVBf3Nyc2pBzvrPynpqQQh3IApqIhdBCndqajYCBCAAIB0gASAKaiAXIAsgCUEKdyIBQX9zcnNqQc76z8p6akEFdyAVaiIUaiAPIBNqIBEgEkEKdyIPcyAQc2pBDXcgDWoiEkEKd2o2AgAgACANIBpqIBAgFnMgEnNqQQt3IA9qIg0gASAgaiAVIBxqIBQgFyAhQX9zcnNqQc76z8p6akEGd2pqNgIQIAAgASAeaiAWaiAPIBtqIBIgGXMgDXNqQQt3ajYCDAuoJAFTfyMAQUBqIglBOGpCADcDACAJQTBqQgA3AwAgCUEoakIANwMAIAlBIGpCADcDACAJQRhqQgA3AwAgCUEQakIANwMAIAlBCGpCADcDACAJQgA3AwAgACgCECEWIAAoAgwhEiAAKAIIIRAgACgCBCEUIAAoAgAhBCACQQZ0IgIEQCABIAJqIVIDQCAJIAEoAAAiAkEYdCACQQh0QYCA/AdxciACQQh2QYD+A3EgAkEYdnJyNgIAIAkgAUEEaigAACICQRh0IAJBCHRBgID8B3FyIAJBCHZBgP4DcSACQRh2cnI2AgQgCSABQQhqKAAAIgJBGHQgAkEIdEGAgPwHcXIgAkEIdkGA/gNxIAJBGHZycjYCCCAJIAFBDGooAAAiAkEYdCACQQh0QYCA/AdxciACQQh2QYD+A3EgAkEYdnJyNgIMIAkgAUEQaigAACICQRh0IAJBCHRBgID8B3FyIAJBCHZBgP4DcSACQRh2cnI2AhAgCSABQRRqKAAAIgJBGHQgAkEIdEGAgPwHcXIgAkEIdkGA/gNxIAJBGHZycjYCFCAJIAFBGGooAAAiAkEYdCACQQh0QYCA/AdxciACQQh2QYD+A3EgAkEYdnJyIgw2AhggCSABQRxqKAAAIgJBGHQgAkEIdEGAgPwHcXIgAkEIdkGA/gNxIAJBGHZyciITNgIcIAkgAUEgaigAACICQRh0IAJBCHRBgID8B3FyIAJBCHZBgP4DcSACQRh2cnIiBjYCICAJIAFBJGooAAAiAkEYdCACQQh0QYCA/AdxciACQQh2QYD+A3EgAkEYdnJyIgU2AiQgCSABQShqKAAAIgJBGHQgAkEIdEGAgPwHcXIgAkEIdkGA/gNxIAJBGHZyciIINgIoIAkgAUEsaigAACICQRh0IAJBCHRBgID8B3FyIAJBCHZBgP4DcSACQRh2cnIiCjYCLCAJIAFBMGooAAAiAkEYdCACQQh0QYCA/AdxciACQQh2QYD+A3EgAkEYdnJyIhE2AjAgCSABQTRqKAAAIgJBGHQgAkEIdEGAgPwHcXIgAkEIdkGA/gNxIAJBGHZyciICNgI0IAkgAUE4aigAACIDQRh0IANBCHRBgID8B3FyIANBCHZBgP4DcSADQRh2cnIiAzYCOCAJIAFBPGooAAAiB0EYdCAHQQh0QYCA/AdxciAHQQh2QYD+A3EgB0EYdnJyIgc2AjwgBCAJKAIMIg4gCSgCBCILcyAFcyADc0EBdyIXIAwgCSgCECINcyARc3NBAXciGCAFIBNzIAdzc0EBdyIZIA0gCSgCCCIVcyAIcyAHc0EBdyIaIBMgCSgCFCJJcyACc3NBAXciG3MgCCARcyAacyAZc0EBdyIcIAIgB3MgG3NzQQF3Ih1zIBUgCSgCACIPcyAGcyACc0EBdyIeIA4gSXMgCnNzQQF3Ih8gBiAMcyADc3NBAXciICAFIApzIBdzc0EBdyIhIAMgEXMgGHNzQQF3IiIgByAXcyAZc3NBAXciIyAYIBpzIBxzc0EBdyIkc0EBdyIlIAYgCHMgHnMgG3NBAXciJiACIApzIB9zc0EBdyInIBsgH3NzIBogHnMgJnMgHXNBAXciKHNBAXciKXMgHCAmcyAocyAlc0EBdyIqIB0gJ3MgKXNzQQF3IitzIAMgHnMgIHMgJ3NBAXciLCAXIB9zICFzc0EBdyItIBggIHMgInNzQQF3Ii4gGSAhcyAjc3NBAXciLyAcICJzICRzc0EBdyIwIB0gI3MgJXNzQQF3IjEgJCAocyAqc3NBAXciMnNBAXciMyAgICZzICxzIClzQQF3IjQgISAncyAtc3NBAXciNSApIC1zcyAoICxzIDRzICtzQQF3IjZzQQF3IjdzICogNHMgNnMgM3NBAXciOCArIDVzIDdzc0EBdyI5cyAiICxzIC5zIDVzQQF3IjogIyAtcyAvc3NBAXciOyAkIC5zIDBzc0EBdyI8ICUgL3MgMXNzQQF3Ij0gKiAwcyAyc3NBAXciPiArIDFzIDNzc0EBdyI/IDIgNnMgOHNzQQF3IkBzQQF3IkcgLiA0cyA6cyA3c0EBdyJBIC8gNXMgO3NzQQF3IkIgNyA7c3MgNiA6cyBBcyA5c0EBdyJDc0EBdyJEcyA4IEFzIENzIEdzQQF3IkogOSBCcyBEc3NBAXciS3MgMCA6cyA8cyBCc0EBdyJFIDEgO3MgPXNzQQF3IkYgMiA8cyA+c3NBAXciSCAzID1zID9zc0EBdyJMIDggPnMgQHNzQQF3Ik0gOSA/cyBHc3NBAXciUyBAIENzIEpzc0EBdyJUc0EBd2ogPCBBcyBFcyBEc0EBdyJOIEMgRXNzIEtzQQF3IlUgPSBCcyBGcyBOc0EBdyJPIEggPyA4IDcgOiAvICQgHSAmIB8gAyAFIA0gBEEedyINaiALIBIgFEEedyILIBBzIARxIBBzamogFiAEQQV3aiAQIBJzIBRxIBJzaiAPakGZ84nUBWoiUEEFd2pBmfOJ1AVqIlFBHnciBCBQQR53Ig9zIBAgFWogUCALIA1zcSALc2ogUUEFd2pBmfOJ1AVqIhVxIA9zaiALIA5qIFEgDSAPc3EgDXNqIBVBBXdqQZnzidQFaiILQQV3akGZ84nUBWoiDkEedyINaiAEIAxqIA4gC0EedyIFIBVBHnciDHNxIAxzaiAPIElqIAQgDHMgC3EgBHNqIA5BBXdqQZnzidQFaiIPQQV3akGZ84nUBWoiDkEedyIEIA9BHnciC3MgDCATaiAPIAUgDXNxIAVzaiAOQQV3akGZ84nUBWoiDHEgC3NqIAUgBmogCyANcyAOcSANc2ogDEEFd2pBmfOJ1AVqIgVBBXdqQZnzidQFaiITQR53IgZqIBEgDEEedyIDaiAIIAtqIAUgAyAEc3EgBHNqIBNBBXdqQZnzidQFaiIIIAYgBUEedyIFc3EgBXNqIAQgCmogEyADIAVzcSADc2ogCEEFd2pBmfOJ1AVqIgpBBXdqQZnzidQFaiIRIApBHnciBCAIQR53IgNzcSADc2ogAiAFaiADIAZzIApxIAZzaiARQQV3akGZ84nUBWoiBUEFd2pBmfOJ1AVqIghBHnciAmogFyARQR53IgZqIAMgB2ogBSAEIAZzcSAEc2ogCEEFd2pBmfOJ1AVqIgcgAiAFQR53IgNzcSADc2ogBCAeaiADIAZzIAhxIAZzaiAHQQV3akGZ84nUBWoiBkEFd2pBmfOJ1AVqIgUgBkEedyIIIAdBHnciBHNxIARzaiADIBpqIAYgAiAEc3EgAnNqIAVBBXdqQZnzidQFaiICQQV3akGZ84nUBWoiA0EedyIHaiAIIBtqIAJBHnciBiAFQR53IgVzIANzaiAEIBhqIAUgCHMgAnNqIANBBXdqQaHX5/YGaiICQQV3akGh1+f2BmoiBEEedyIDIAJBHnciCHMgBSAgaiAGIAdzIAJzaiAEQQV3akGh1+f2BmoiAnNqIAYgGWogByAIcyAEc2ogAkEFd2pBodfn9gZqIgRBBXdqQaHX5/YGaiIHQR53IgZqIAMgHGogBEEedyIFIAJBHnciAnMgB3NqIAggIWogAiADcyAEc2ogB0EFd2pBodfn9gZqIgRBBXdqQaHX5/YGaiIDQR53IgcgBEEedyIIcyACICdqIAUgBnMgBHNqIANBBXdqQaHX5/YGaiICc2ogBSAiaiAGIAhzIANzaiACQQV3akGh1+f2BmoiBEEFd2pBodfn9gZqIgNBHnciBmogByAjaiAEQR53IgUgAkEedyICcyADc2ogCCAsaiACIAdzIARzaiADQQV3akGh1+f2BmoiBEEFd2pBodfn9gZqIgNBHnciByAEQR53IghzIAIgKGogBSAGcyAEc2ogA0EFd2pBodfn9gZqIgJzaiAFIC1qIAYgCHMgA3NqIAJBBXdqQaHX5/YGaiIEQQV3akGh1+f2BmoiA0EedyIGaiAHIC5qIARBHnciBSACQR53IgJzIANzaiAIIClqIAIgB3MgBHNqIANBBXdqQaHX5/YGaiIEQQV3akGh1+f2BmoiA0EedyIHIARBHnciCHMgAiAlaiAFIAZzIARzaiADQQV3akGh1+f2BmoiCnNqIAUgNGogBiAIcyADc2ogCkEFd2pBodfn9gZqIgZBBXdqQaHX5/YGaiIFQR53IgJqIAcgNWogBkEedyIEIApBHnciA3MgBXEgAyAEcXNqIAggKmogAyAHcyAGcSADIAdxc2ogBUEFd2pB3Pnu+HhqIgVBBXdqQdz57vh4aiIIQR53IgcgBUEedyIGcyADIDBqIAUgAiAEc3EgAiAEcXNqIAhBBXdqQdz57vh4aiIDcSAGIAdxc2ogBCAraiAIIAIgBnNxIAIgBnFzaiADQQV3akHc+e74eGoiBUEFd2pB3Pnu+HhqIghBHnciAmogByA2aiAIIAVBHnciBCADQR53IgNzcSADIARxc2ogBiAxaiADIAdzIAVxIAMgB3FzaiAIQQV3akHc+e74eGoiBUEFd2pB3Pnu+HhqIghBHnciByAFQR53IgZzIAMgO2ogBSACIARzcSACIARxc2ogCEEFd2pB3Pnu+HhqIgNxIAYgB3FzaiAEIDJqIAIgBnMgCHEgAiAGcXNqIANBBXdqQdz57vh4aiIFQQV3akHc+e74eGoiCEEedyICaiBBIANBHnciBGogBiA8aiAFIAQgB3NxIAQgB3FzaiAIQQV3akHc+e74eGoiBiACIAVBHnciA3NxIAIgA3FzaiAHIDNqIAggAyAEc3EgAyAEcXNqIAZBBXdqQdz57vh4aiIFQQV3akHc+e74eGoiCCAFQR53IgQgBkEedyIHc3EgBCAHcXNqIAMgPWogAiAHcyAFcSACIAdxc2ogCEEFd2pB3Pnu+HhqIgZBBXdqQdz57vh4aiIFQR53IgJqIDkgCEEedyIDaiAHIEJqIAYgAyAEc3EgAyAEcXNqIAVBBXdqQdz57vh4aiIIIAIgBkEedyIHc3EgAiAHcXNqIAQgPmogAyAHcyAFcSADIAdxc2ogCEEFd2pB3Pnu+HhqIgZBBXdqQdz57vh4aiIFIAZBHnciAyAIQR53IgRzcSADIARxc2ogByBFaiAGIAIgBHNxIAIgBHFzaiAFQQV3akHc+e74eGoiAkEFd2pB3Pnu+HhqIgdBHnciBmogAyBGaiACQR53IgggBUEedyIFcyAHc2ogBCBDaiADIAVzIAJzaiAHQQV3akHWg4vTfGoiAkEFd2pB1oOL03xqIgRBHnciAyACQR53IgdzIAUgQGogBiAIcyACc2ogBEEFd2pB1oOL03xqIgJzaiAIIERqIAYgB3MgBHNqIAJBBXdqQdaDi9N8aiIEQQV3akHWg4vTfGoiBkEedyIFaiADIE5qIARBHnciCCACQR53IgJzIAZzaiAHIEdqIAIgA3MgBHNqIAZBBXdqQdaDi9N8aiIEQQV3akHWg4vTfGoiA0EedyIHIARBHnciBnMgAiBMaiAFIAhzIARzaiADQQV3akHWg4vTfGoiAnNqIAggSmogBSAGcyADc2ogAkEFd2pB1oOL03xqIgRBBXdqQdaDi9N8aiIDQR53IgVqIAcgS2ogBEEedyIIIAJBHnciAnMgA3NqIAYgTWogAiAHcyAEc2ogA0EFd2pB1oOL03xqIgRBBXdqQdaDi9N8aiIDQR53IgcgBEEedyIGcyA+IEVzIEhzIE9zQQF3IgogAmogBSAIcyAEc2ogA0EFd2pB1oOL03xqIgJzaiAIIFNqIAUgBnMgA3NqIAJBBXdqQdaDi9N8aiIEQQV3akHWg4vTfGoiA0EedyIFaiAHIFRqIARBHnciCCACQR53IgJzIANzaiAGID8gRnMgTHMgCnNBAXciBmogAiAHcyAEc2ogA0EFd2pB1oOL03xqIgRBBXdqQdaDi9N8aiIDQR53IgogBEEedyIHcyBEIEZzIE9zIFVzQQF3IAJqIAUgCHMgBHNqIANBBXdqQdaDi9N8aiICc2ogQCBIcyBNcyAGc0EBdyAIaiAFIAdzIANzaiACQQV3akHWg4vTfGoiA0EFd2pB1oOL03xqIQQgAyAUaiEUIAogEmohEiACQR53IBBqIRAgByAWaiEWIAFBQGsiASBSRw0ACwsgACAWNgIQIAAgEjYCDCAAIBA2AgggACAUNgIEIAAgBDYCAAugKgIIfwF+AkACQAJAAkACQAJAIABB9QFPBEAgAEHN/3tPDQQgAEELaiIAQXhxIQZB6KHAACgCACIHRQ0BQQAgBmshBQJAAkACf0EAIABBCHYiAEUNABpBHyAGQf///wdLDQAaIAZBBiAAZyIAa0EfcXZBAXEgAEEBdGtBPmoLIghBAnRB9KPAAGooAgAiAARAIAZBAEEZIAhBAXZrQR9xIAhBH0YbdCEDA0ACQCAAQQRqKAIAQXhxIgQgBkkNACAEIAZrIgQgBU8NACAAIQIgBCIFDQBBACEFDAMLIABBFGooAgAiBCABIAQgACADQR12QQRxakEQaigCACIARxsgASAEGyEBIANBAXQhAyAADQALIAEEQCABIQAMAgsgAg0CC0EAIQJBAiAIQR9xdCIAQQAgAGtyIAdxIgBFDQMgAEEAIABrcWhBAnRB9KPAAGooAgAiAEUNAwsDQCAAIAIgAEEEaigCAEF4cSIBIAZPIAEgBmsiAyAFSXEiBBshAiADIAUgBBshBSAAKAIQIgEEfyABBSAAQRRqKAIACyIADQALIAJFDQILQfSkwAAoAgAiACAGT0EAIAUgACAGa08bDQEgAigCGCEHAkACQCACIAIoAgwiAUYEQCACQRRBECACQRRqIgMoAgAiARtqKAIAIgANAUEAIQEMAgsgAigCCCIAIAE2AgwgASAANgIIDAELIAMgAkEQaiABGyEDA0AgAyEEIAAiAUEUaiIDKAIAIgBFBEAgAUEQaiEDIAEoAhAhAAsgAA0ACyAEQQA2AgALAkAgB0UNAAJAIAIgAigCHEECdEH0o8AAaiIAKAIARwRAIAdBEEEUIAcoAhAgAkYbaiABNgIAIAFFDQIMAQsgACABNgIAIAENAEHoocAAQeihwAAoAgBBfiACKAIcd3E2AgAMAQsgASAHNgIYIAIoAhAiAARAIAEgADYCECAAIAE2AhgLIAJBFGooAgAiAEUNACABQRRqIAA2AgAgACABNgIYCwJAIAVBEE8EQCACIAZBA3I2AgQgAiAGaiIHIAVBAXI2AgQgBSAHaiAFNgIAIAVBgAJPBEAgB0IANwIQIAcCf0EAIAVBCHYiAUUNABpBHyAFQf///wdLDQAaIAVBBiABZyIAa0EfcXZBAXEgAEEBdGtBPmoLIgA2AhwgAEECdEH0o8AAaiEEAkACQAJAAkBB6KHAACgCACIDQQEgAEEfcXQiAXEEQCAEKAIAIgNBBGooAgBBeHEgBUcNASADIQAMAgtB6KHAACABIANyNgIAIAQgBzYCACAHIAQ2AhgMAwsgBUEAQRkgAEEBdmtBH3EgAEEfRht0IQEDQCADIAFBHXZBBHFqQRBqIgQoAgAiAEUNAiABQQF0IQEgACEDIABBBGooAgBBeHEgBUcNAAsLIAAoAggiASAHNgIMIAAgBzYCCCAHQQA2AhggByAANgIMIAcgATYCCAwECyAEIAc2AgAgByADNgIYCyAHIAc2AgwgByAHNgIIDAILIAVBA3YiAUEDdEHsocAAaiEAAn9B5KHAACgCACIDQQEgAXQiAXEEQCAAKAIIDAELQeShwAAgASADcjYCACAACyEFIAAgBzYCCCAFIAc2AgwgByAANgIMIAcgBTYCCAwBCyACIAUgBmoiAEEDcjYCBCAAIAJqIgAgACgCBEEBcjYCBAsgAkEIag8LAkACQEHkocAAKAIAIgdBECAAQQtqQXhxIABBC0kbIgZBA3YiAXYiAkEDcUUEQCAGQfSkwAAoAgBNDQMgAg0BQeihwAAoAgAiAEUNAyAAQQAgAGtxaEECdEH0o8AAaigCACIBQQRqKAIAQXhxIAZrIQUgASEDA0AgASgCECIARQRAIAFBFGooAgAiAEUNBAsgAEEEaigCAEF4cSAGayICIAUgAiAFSSICGyEFIAAgAyACGyEDIAAhAQwACwALAkAgAkF/c0EBcSABaiIDQQN0IgBB9KHAAGooAgAiAUEIaiIFKAIAIgIgAEHsocAAaiIARwRAIAIgADYCDCAAIAI2AggMAQtB5KHAACAHQX4gA3dxNgIACyABIANBA3QiAEEDcjYCBCAAIAFqIgAgACgCBEEBcjYCBAwFCwJAQQIgAXQiAEEAIABrciACIAF0cSIAQQAgAGtxaCIBQQN0IgBB9KHAAGooAgAiA0EIaiIEKAIAIgIgAEHsocAAaiIARwRAIAIgADYCDCAAIAI2AggMAQtB5KHAACAHQX4gAXdxNgIACyADIAZBA3I2AgQgAyAGaiIFIAFBA3QiACAGayIHQQFyNgIEIAAgA2ogBzYCAEH0pMAAKAIAIgAEQCAAQQN2IgJBA3RB7KHAAGohAEH8pMAAKAIAIQgCf0HkocAAKAIAIgFBASACQR9xdCICcQRAIAAoAggMAQtB5KHAACABIAJyNgIAIAALIQMgACAINgIIIAMgCDYCDCAIIAA2AgwgCCADNgIIC0H8pMAAIAU2AgBB9KTAACAHNgIAIAQPCyADKAIYIQcCQAJAIAMgAygCDCIBRgRAIANBFEEQIANBFGoiASgCACICG2ooAgAiAA0BQQAhAQwCCyADKAIIIgAgATYCDCABIAA2AggMAQsgASADQRBqIAIbIQIDQCACIQQgACIBQRRqIgIoAgAiAEUEQCABQRBqIQIgASgCECEACyAADQALIARBADYCAAsgB0UNAiADIAMoAhxBAnRB9KPAAGoiACgCAEcEQCAHQRBBFCAHKAIQIANGG2ogATYCACABRQ0DDAILIAAgATYCACABDQFB6KHAAEHoocAAKAIAQX4gAygCHHdxNgIADAILAkACQAJAAkBB9KTAACgCACIBIAZJBEBB+KTAACgCACIAIAZLDQlBACEFIAZBr4AEaiICQRB2QAAiAEF/Rg0HIABBEHQiA0UNB0GEpcAAIAJBgIB8cSIFQYSlwAAoAgBqIgI2AgBBiKXAAEGIpcAAKAIAIgAgAiAAIAJLGzYCAEGApcAAKAIAIgRFDQFBjKXAACEAA0AgACgCACIBIAAoAgQiAmogA0YNAyAAKAIIIgANAAsMAwtB/KTAACgCACEDAn8gASAGayICQQ9NBEBB/KTAAEEANgIAQfSkwABBADYCACADIAFBA3I2AgQgASADaiICQQRqIQAgAigCBEEBcgwBC0H0pMAAIAI2AgBB/KTAACADIAZqIgA2AgAgACACQQFyNgIEIAEgA2ogAjYCACADQQRqIQAgBkEDcgshBiAAIAY2AgAMBwtBoKXAACgCACIAQQAgACADTRtFBEBBoKXAACADNgIAC0GkpcAAQf8fNgIAQZClwAAgBTYCAEGMpcAAIAM2AgBB+KHAAEHsocAANgIAQYCiwABB9KHAADYCAEH0ocAAQeyhwAA2AgBBiKLAAEH8ocAANgIAQfyhwABB9KHAADYCAEGQosAAQYSiwAA2AgBBhKLAAEH8ocAANgIAQZiiwABBjKLAADYCAEGMosAAQYSiwAA2AgBBoKLAAEGUosAANgIAQZSiwABBjKLAADYCAEGoosAAQZyiwAA2AgBBnKLAAEGUosAANgIAQbCiwABBpKLAADYCAEGkosAAQZyiwAA2AgBBmKXAAEEANgIAQbiiwABBrKLAADYCAEGsosAAQaSiwAA2AgBBtKLAAEGsosAANgIAQcCiwABBtKLAADYCAEG8osAAQbSiwAA2AgBByKLAAEG8osAANgIAQcSiwABBvKLAADYCAEHQosAAQcSiwAA2AgBBzKLAAEHEosAANgIAQdiiwABBzKLAADYCAEHUosAAQcyiwAA2AgBB4KLAAEHUosAANgIAQdyiwABB1KLAADYCAEHoosAAQdyiwAA2AgBB5KLAAEHcosAANgIAQfCiwABB5KLAADYCAEHsosAAQeSiwAA2AgBB+KLAAEHsosAANgIAQYCjwABB9KLAADYCAEH0osAAQeyiwAA2AgBBiKPAAEH8osAANgIAQfyiwABB9KLAADYCAEGQo8AAQYSjwAA2AgBBhKPAAEH8osAANgIAQZijwABBjKPAADYCAEGMo8AAQYSjwAA2AgBBoKPAAEGUo8AANgIAQZSjwABBjKPAADYCAEGoo8AAQZyjwAA2AgBBnKPAAEGUo8AANgIAQbCjwABBpKPAADYCAEGko8AAQZyjwAA2AgBBuKPAAEGso8AANgIAQayjwABBpKPAADYCAEHAo8AAQbSjwAA2AgBBtKPAAEGso8AANgIAQcijwABBvKPAADYCAEG8o8AAQbSjwAA2AgBB0KPAAEHEo8AANgIAQcSjwABBvKPAADYCAEHYo8AAQcyjwAA2AgBBzKPAAEHEo8AANgIAQeCjwABB1KPAADYCAEHUo8AAQcyjwAA2AgBB6KPAAEHco8AANgIAQdyjwABB1KPAADYCAEHwo8AAQeSjwAA2AgBB5KPAAEHco8AANgIAQYClwAAgAzYCAEHso8AAQeSjwAA2AgBB+KTAACAFQVhqIgA2AgAgAyAAQQFyNgIEIAAgA2pBKDYCBEGcpcAAQYCAgAE2AgAMAgsgAEEMaigCACADIARNciABIARLcg0AIAAgAiAFajYCBEGApcAAQYClwAAoAgAiA0EPakF4cSIBQXhqNgIAQfikwABB+KTAACgCACAFaiICIAMgAWtqQQhqIgA2AgAgAUF8aiAAQQFyNgIAIAIgA2pBKDYCBEGcpcAAQYCAgAE2AgAMAQtBoKXAAEGgpcAAKAIAIgAgAyAAIANJGzYCACADIAVqIQFBjKXAACEAAkADQCABIAAoAgBHBEAgACgCCCIADQEMAgsLIABBDGooAgANACAAIAM2AgAgACAAKAIEIAVqNgIEIAMgBkEDcjYCBCADIAZqIQQgASADayAGayEGAkACQCABQYClwAAoAgBHBEBB/KTAACgCACABRg0BIAFBBGooAgAiAEEDcUEBRgRAIAEgAEF4cSIAEEwgACAGaiEGIAAgAWohAQsgASABKAIEQX5xNgIEIAQgBkEBcjYCBCAEIAZqIAY2AgAgBkGAAk8EQCAEQgA3AhAgBAJ/QQAgBkEIdiIARQ0AGkEfIAZB////B0sNABogBkEGIABnIgBrQR9xdkEBcSAAQQF0a0E+agsiBTYCHCAFQQJ0QfSjwABqIQECQAJAAkACQEHoocAAKAIAIgJBASAFQR9xdCIAcQRAIAEoAgAiAkEEaigCAEF4cSAGRw0BIAIhBQwCC0HoocAAIAAgAnI2AgAgASAENgIAIAQgATYCGAwDCyAGQQBBGSAFQQF2a0EfcSAFQR9GG3QhAQNAIAIgAUEddkEEcWpBEGoiACgCACIFRQ0CIAFBAXQhASAFIgJBBGooAgBBeHEgBkcNAAsLIAUoAggiACAENgIMIAUgBDYCCCAEQQA2AhggBCAFNgIMIAQgADYCCAwFCyAAIAQ2AgAgBCACNgIYCyAEIAQ2AgwgBCAENgIIDAMLIAZBA3YiAkEDdEHsocAAaiEAAn9B5KHAACgCACIBQQEgAnQiAnEEQCAAKAIIDAELQeShwAAgASACcjYCACAACyEFIAAgBDYCCCAFIAQ2AgwgBCAANgIMIAQgBTYCCAwCC0GApcAAIAQ2AgBB+KTAAEH4pMAAKAIAIAZqIgA2AgAgBCAAQQFyNgIEDAELQfykwAAgBDYCAEH0pMAAQfSkwAAoAgAgBmoiADYCACAEIABBAXI2AgQgACAEaiAANgIACwwFC0GMpcAAIQADQAJAIAAoAgAiAiAETQRAIAIgACgCBGoiAiAESw0BCyAAKAIIIQAMAQsLQYClwAAgAzYCAEH4pMAAIAVBWGoiADYCACADIABBAXI2AgQgACADakEoNgIEQZylwABBgICAATYCACAEIAJBYGpBeHFBeGoiACAAIARBEGpJGyIBQRs2AgRBjKXAACkCACEJIAFBEGpBlKXAACkCADcCACABIAk3AghBkKXAACAFNgIAQYylwAAgAzYCAEGUpcAAIAFBCGo2AgBBmKXAAEEANgIAIAFBHGohAANAIABBBzYCACACIABBBGoiAEsNAAsgASAERg0AIAEgASgCBEF+cTYCBCAEIAEgBGsiBUEBcjYCBCABIAU2AgAgBUGAAk8EQCAEQgA3AhAgBEEcagJ/QQAgBUEIdiICRQ0AGkEfIAVB////B0sNABogBUEGIAJnIgBrQR9xdkEBcSAAQQF0a0E+agsiADYCACAAQQJ0QfSjwABqIQMCQAJAAkACQEHoocAAKAIAIgFBASAAQR9xdCICcQRAIAMoAgAiAkEEaigCAEF4cSAFRw0BIAIhAAwCC0HoocAAIAEgAnI2AgAgAyAENgIAIARBGGogAzYCAAwDCyAFQQBBGSAAQQF2a0EfcSAAQR9GG3QhAQNAIAIgAUEddkEEcWpBEGoiAygCACIARQ0CIAFBAXQhASAAIQIgAEEEaigCAEF4cSAFRw0ACwsgACgCCCICIAQ2AgwgACAENgIIIARBGGpBADYCACAEIAA2AgwgBCACNgIIDAMLIAMgBDYCACAEQRhqIAI2AgALIAQgBDYCDCAEIAQ2AggMAQsgBUEDdiICQQN0QeyhwABqIQACf0HkocAAKAIAIgFBASACdCICcQRAIAAoAggMAQtB5KHAACABIAJyNgIAIAALIQEgACAENgIIIAEgBDYCDCAEIAA2AgwgBCABNgIIC0EAIQVB+KTAACgCACIAIAZNDQIMBAsgASAHNgIYIAMoAhAiAARAIAEgADYCECAAIAE2AhgLIANBFGooAgAiAEUNACABQRRqIAA2AgAgACABNgIYCwJAIAVBEE8EQCADIAZBA3I2AgQgAyAGaiIEIAVBAXI2AgQgBCAFaiAFNgIAQfSkwAAoAgAiAARAIABBA3YiAkEDdEHsocAAaiEAQfykwAAoAgAhBwJ/QeShwAAoAgAiAUEBIAJBH3F0IgJxBEAgACgCCAwBC0HkocAAIAEgAnI2AgAgAAshAiAAIAc2AgggAiAHNgIMIAcgADYCDCAHIAI2AggLQfykwAAgBDYCAEH0pMAAIAU2AgAMAQsgAyAFIAZqIgBBA3I2AgQgACADaiIAIAAoAgRBAXI2AgQLDAELIAUPCyADQQhqDwtB+KTAACAAIAZrIgI2AgBBgKXAAEGApcAAKAIAIgEgBmoiADYCACAAIAJBAXI2AgQgASAGQQNyNgIEIAFBCGoL8REBFH8gACgCACELIAAoAgwhBCAAKAIIIQUgACgCBCEDIwBBQGoiAkEYaiIGQgA3AwAgAkEgaiIHQgA3AwAgAkE4aiIIQgA3AwAgAkEwaiIJQgA3AwAgAkEoaiIKQgA3AwAgAkEIaiIMIAEpAAg3AwAgAkEQaiINIAEpABA3AwAgBiABKAAYIgY2AgAgByABKAAgIgc2AgAgAiABKQAANwMAIAIgASgAHCIONgIcIAIgASgAJCIPNgIkIAogASgAKCIKNgIAIAIgASgALCIQNgIsIAkgASgAMCIJNgIAIAIgASgANCIRNgI0IAggASgAOCIINgIAIAIgASgAPCISNgI8IAAgDSgCACINIAcgCSACKAIAIhMgDyARIAIoAgQiFCACKAIUIhUgESAPIBUgFCAJIAcgDSADIBMgCyAEIANBf3NxIAMgBXFyampB+Miqu31qQQd3aiIBaiAEIBRqIAUgAUF/c3EgASADcXJqQdbunsZ+akEMdyABaiIEIAMgAigCDCILaiABIAQgBSAMKAIAIgxqIAMgBEF/c3EgASAEcXJqQdvhgaECakERd2oiAkF/c3EgAiAEcXJqQe6d9418akEWdyACaiIBQX9zcSABIAJxcmpBr5/wq39qQQd3IAFqIgNqIAQgFWogAiADQX9zcSABIANxcmpBqoyfvARqQQx3IANqIgQgASAOaiADIAQgAiAGaiABIARBf3NxIAMgBHFyakGTjMHBempBEXdqIgFBf3NxIAEgBHFyakGBqppqakEWdyABaiICQX9zcSABIAJxcmpB2LGCzAZqQQd3IAJqIgNqIAQgD2ogASADQX9zcSACIANxcmpBr++T2nhqQQx3IANqIgQgAiAQaiADIAQgASAKaiACIARBf3NxIAMgBHFyakGxt31qQRF3aiIBQX9zcSABIARxcmpBvq/zynhqQRZ3IAFqIgJBf3NxIAEgAnFyakGiosDcBmpBB3cgAmoiA2ogAiASaiADIAEgCGogAiADIAQgEWogASADQX9zcSACIANxcmpBk+PhbGpBDHdqIgFBf3MiBHEgASADcXJqQY6H5bN6akERdyABaiICQX9zIgVxIAEgAnFyakGhkNDNBGpBFncgAmoiAyABcSACIARxcmpB4sr4sH9qQQV3IANqIgRqIAMgE2ogAiAQaiABIAZqIAIgBHEgAyAFcXJqQcDmgoJ8akEJdyAEaiIBIANxIAQgA0F/c3FyakHRtPmyAmpBDncgAWoiAiAEcSABIARBf3NxcmpBqo/bzX5qQRR3IAJqIgMgAXEgAiABQX9zcXJqQd2gvLF9akEFdyADaiIEaiADIA1qIAIgEmogASAKaiACIARxIAMgAkF/c3FyakHTqJASakEJdyAEaiIBIANxIAQgA0F/c3FyakGBzYfFfWpBDncgAWoiAiAEcSABIARBf3NxcmpByPfPvn5qQRR3IAJqIgMgAXEgAiABQX9zcXJqQeabh48CakEFdyADaiIEaiADIAdqIAIgC2ogASAIaiACIARxIAMgAkF/c3FyakHWj9yZfGpBCXcgBGoiASADcSAEIANBf3NxcmpBh5vUpn9qQQ53IAFqIgIgBHEgASAEQX9zcXJqQe2p6KoEakEUdyACaiIDIAFxIAIgAUF/c3FyakGF0o/PempBBXcgA2oiBGogAyAJaiACIA5qIAEgDGogAiAEcSADIAJBf3NxcmpB+Me+Z2pBCXcgBGoiASADcSAEIANBf3NxcmpB2YW8uwZqQQ53IAFqIgMgBHEgASAEQX9zcXJqQYqZqel4akEUdyADaiIEIANzIgUgAXNqQcLyaGpBBHcgBGoiAmogAyAQaiABIAdqIAIgBXNqQYHtx7t4akELdyACaiIBIAIgBHNzakGiwvXsBmpBEHcgAWoiAyABcyAEIAhqIAEgAnMgA3NqQYzwlG9qQRd3IANqIgJzakHE1PulempBBHcgAmoiBGogAyAOaiABIA1qIAIgA3MgBHNqQamf+94EakELdyAEaiIBIAIgBHNzakHglu21f2pBEHcgAWoiAyABcyACIApqIAEgBHMgA3NqQfD4/vV7akEXdyADaiICc2pBxv3txAJqQQR3IAJqIgRqIAMgC2ogASATaiACIANzIARzakH6z4TVfmpBC3cgBGoiASACIARzc2pBheG8p31qQRB3IAFqIgMgAXMgAiAGaiABIARzIANzakGFuqAkakEXdyADaiICc2pBuaDTzn1qQQR3IAJqIgRqIAIgDGogASAJaiACIANzIARzakHls+62fmpBC3cgBGoiASAEcyADIBJqIAIgBHMgAXNqQfj5if0BakEQdyABaiICc2pB5ayxpXxqQRd3IAJqIgMgAUF/c3IgAnNqQcTEpKF/akEGdyADaiIEaiADIBVqIAIgCGogASAOaiAEIAJBf3NyIANzakGX/6uZBGpBCncgBGoiASADQX9zciAEc2pBp8fQ3HpqQQ93IAFqIgIgBEF/c3IgAXNqQbnAzmRqQRV3IAJqIgMgAUF/c3IgAnNqQcOz7aoGakEGdyADaiIEaiADIBRqIAIgCmogASALaiAEIAJBf3NyIANzakGSmbP4eGpBCncgBGoiASADQX9zciAEc2pB/ei/f2pBD3cgAWoiAiAEQX9zciABc2pB0buRrHhqQRV3IAJqIgMgAUF/c3IgAnNqQc/8of0GakEGdyADaiIEaiADIBFqIAIgBmogASASaiAEIAJBf3NyIANzakHgzbNxakEKdyAEaiIBIANBf3NyIARzakGUhoWYempBD3cgAWoiAiAEQX9zciABc2pBoaOg8ARqQRV3IAJqIgMgAUF/c3IgAnNqQYL9zbp/akEGdyADaiIEIAAoAgBqNgIAIAAgASAQaiAEIAJBf3NyIANzakG15Ovpe2pBCncgBGoiASAAKAIMajYCDCAAIAIgDGogASADQX9zciAEc2pBu6Xf1gJqQQ93IAFqIgIgACgCCGo2AgggACACIAAoAgRqIAMgD2ogAiAEQX9zciABc2pBkaeb3H5qQRV3ajYCBAvcDwEFfyAAIAEtAAAiAzoAECAAIAEtAAEiAjoAESAAIAEtAAIiBDoAEiAAIAEtAAMiBToAEyAAIAEtAAQiBjoAFCAAIAMgAC0AAHM6ACAgACACIAAtAAFzOgAhIAAgBCAALQACczoAIiAAIAUgAC0AA3M6ACMgACAGIAAt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BCARIAEgA0F/c3EgAyAEcXIgAmpqQQd3IgVBf3NxIAMgBXFyIAFqakELdyIBIAVyIBIgBCABIAVxIgQgAyABQX9zcXJqakETdyICcSAEcmogFGpBmfOJ1AVqQQN3IgMgByABIAUgAyABIAJycSABIAJxcmogDWpBmfOJ1AVqQQV3IgQgAiADcnEgAiADcXJqakGZ84nUBWpBCXciASAEciAJIAIgASADIARycSADIARxcmpqQZnzidQFakENdyICcSABIARxcmogDGpBmfOJ1AVqQQN3IgMgDyABIAQgAyABIAJycSABIAJxcmogFWpBmfOJ1AVqQQV3IgQgAiADcnEgAiADcXJqakGZ84nUBWpBCXciASAEciARIAIgASADIARycSADIARxcmpqQZnzidQFakENdyICcSABIARxcmogC2pBmfOJ1AVqQQN3IgMgCiABIAYgBCADIAEgAnJxIAEgAnFyampBmfOJ1AVqQQV3IgQgAiADcnEgAiADcXJqakGZ84nUBWpBCXciASAEciAIIAIgASADIARycSADIARxcmpqQZnzidQFakENdyICcSABIARxcmogE2pBmfOJ1AVqQQN3IgMgEiACIBAgASAOIAQgAyABIAJycSABIAJxcmpqQZnzidQFakEFdyIEIAIgA3JxIAIgA3FyampBmfOJ1AVqQQl3IgUgAyAEcnEgAyAEcXJqakGZ84nUBWpBDXciAyAFcyICIARzaiAUakGh1+f2BmpBA3ciASAJIAMgASAHIAQgASACc2pqQaHX5/YGakEJdyICcyAFIA1qIAEgA3MgAnNqQaHX5/YGakELdyIEc2pqQaHX5/YGakEPdyIDIARzIgUgAnNqIAtqQaHX5/YGakEDdyIBIAggAyABIAogAiABIAVzampBodfn9gZqQQl3IgJzIAQgBmogASADcyACc2pBodfn9gZqQQt3IgRzampBodfn9gZqQQ93IgMgBHMiBSACc2ogDGpBodfn9gZqQQN3IgEgESADIAEgDyACIAEgBXNqakGh1+f2BmpBCXciAnMgBCAVaiABIANzIAJzakGh1+f2BmpBC3ciBHNqakGh1+f2BmpBD3ciAyAEcyIFIAJzaiATakGh1+f2BmpBA3ciASAAKAIAajYCACAAIBAgAiABIAVzampBodfn9gZqQQl3IgIgACgCDGo2Agwg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IgVFDQULIAIgBDYCFCACIAU2AhALIAIoAhAhBSACQThqIgZCADcDACACQTBqIgdCADcDACACQShqIghCADcDACACQSBqIglCADcDACACQRhqIgpCADcDACACQgA3AxAgAkHqAGpCADcBACACQfIAakEAOwEAIAJBEDYCYCACQQA7AWQgAkEANgFmIAJBiAFqIAJB8ABqKAIANgIAIAJBgAFqIAJB6ABqKQMANwMAIAJB2ABqIgsgAkGEAWopAgA3AwAgAiACKQNgNwN4IAIgAikCfDcDUCACQcgAaiIMIAspAwA3AwAgAiACKQNQNwNAIANBOGogDCkDADcAACADQTBqIAIpA0A3AAAgA0EoaiAGKQMANwAAIANBIGogBykDADcAACADQRhqIAgpAwA3AAAgA0EQaiAJKQMANwAAIANBCGogCikDADcAACADIAIpAxA3AAAgAUEANgIAIAAgBDYCBCAAIAU2AgAgAkGQAWokAA8LQbCawABBFyACQRBqQaCXwABBsJfAABB5AAtBEEEBQbSlwAAoAgAiAEECIAAbEQAAAAtBh4zAAEEkQayMwAAQiAEACyAEQQFBtKXAACgCACIAQQIgABsRAAAAC9gIAQV/IABBeGoiASAAQXxqKAIAIgNBeHEiAGohAgJAAkACQAJAIANBAXENACADQQNxRQ0BIAEoAgAiAyAAaiEAIAEgA2siAUH8pMAAKAIARgRAIAIoAgRBA3FBA0cNAUH0pMAAIAA2AgAgAiACKAIEQX5xNgIEIAEgAEEBcjYCBCAAIAFqIAA2AgAPCyABIAMQTAsCQCACQQRqIgQoAgAiA0ECcQRAIAQgA0F+cTYCACABIABBAXI2AgQgACABaiAANgIADAELAkAgAkGApcAAKAIARwRAQfykwAAoAgAgAkYNASACIANBeHEiAhBMIAEgACACaiIAQQFyNgIEIAAgAWogADYCACABQfykwAAoAgBHDQJB9KTAACAANgIADwtBgKXAACABNgIAQfikwABB+KTAACgCACAAaiIANgIAIAEgAEEBcjYCBEH8pMAAKAIAIAFGBEBB9KTAAEEANgIAQfykwABBADYCAAtBnKXAACgCACICIABPDQJBgKXAACgCACIARQ0CAkBB+KTAACgCACIDQSlJDQBBjKXAACEBA0AgASgCACIEIABNBEAgBCABKAIE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KQMwNwNoIAJBIGogAkGMAWopAgA3AwAgAkEYaiACQYQBaikCADcDACACQRBqIAJB/ABqKQIANwMAIAJBCGogAkH0AGopAgA3AwAgAkEoaiACQZQBaikCADcDACACIAIpAmw3AwAgASACEB8gAUIANwMIIAFCADcDACABQQA2AlAgAUHQmMAAKQMANwMQIAFBGGpB2JjAACkDADcDACABQSBqQeCYwAApAwA3AwAgAUEoakHomMAAKQMANwMAIAFBMGpB8JjAACkDADcDACABQThqQfiYwAApAwA3AwAgAUFAa0GAmcAAKQMANwMAIAFByABqQYiZwAApAwA3AwACQAJAQTBBARChASIDBEAgAkIwNwJsIAIgAzYCaCACQegAaiACQTAQXgJAIAIoAmwiBCACKAJwIgNGBEAgBCEDDAELIAQgA0kNAiAERQ0AIAIoAmghBQJAIANFBEAgBRAQQQEhBAwBCyAFIARBASADEJoBIgRFDQQLIAIgAzYCbCACIAQ2AmgLIAIoAmghBCABQgA3AwggAUIANwMAIAFBADYCUCABQRBqIgFB0JjAACkDADcDACABQQhqQdiYwAApAwA3AwAgAUEQakHgmMAAKQMANwMAIAFBGGpB6JjAACkDADcDACABQSBqQfCYwAApAwA3AwAgAUEoakH4mMAAKQMANwMAIAFBMGpBgJnAACkDADcDACABQThqQYiZwAApAwA3AwAgACADNgIEIAAgBDYCACACQaABaiQADwtBMEEBQbSlwAAoAgAiAEECIAAbEQAAAAtBh4zAAEEkQayMwAAQiAEACyADQQFBtKXAACgCACIAQQIgABsRAAAAC78GAQR/IAAgAWohAgJAAkACQAJAAkAgAEEEaigCACIDQQFxDQAgA0EDcUUNASAAKAIAIgMgAWohASAAIANrIgBB/KTAACgCAEYEQCACKAIEQQNxQQNHDQFB9KTAACABNgIAIAIgAigCBEF+cTYCBCAAIAFBAXI2AgQgAiABNgIADwsgACADEEwLAkAgAkEEaigCACIDQQJxBEAgAkEEaiADQX5xNgIAIAAgAUEBcjYCBCAAIAFqIAE2AgAMAQsCQCACQYClwAAoAgBHBEBB/KTAACgCACACRg0BIAIgA0F4cSICEEwgACABIAJqIgFBAXI2AgQgACABaiABNgIAIABB/KTAACgCAEcNAkH0pMAAIAE2AgAPC0GApcAAIAA2AgBB+KTAAEH4pMAAKAIAIAFqIgE2AgAgACABQQFyNgIEIABB/KTAACgCAEcNAkH0pMAAQQA2AgBB/KTAAEEANgIADwtB/KTAACAANgIAQfSkwABB9KTAACgCACABaiIBNgIAIAAgAUEBcjYCBCAAIAFqIAE2AgAPCyABQYACSQ0DIABCADcCECAAQRxqAn9BACABQQh2IgNFDQAaQR8gAUH///8HSw0AGiABQQYgA2ciAmtBH3F2QQFxIAJBAXRrQT5qCyICNgIAIAJBAnRB9KPAAGohAwJAAkBB6KHAACgCACIEQQEgAkEfcXQiBXEEQCADKAIAIgNBBGooAgBBeHEgAUcNASADIQIMAgtB6KHAACAEIAVyNgIAIAMgADYCAAwECyABQQBBGSACQQF2a0EfcSACQR9GG3QhBANAIAMgBEEddkEEcWpBEGoiBSgCACICRQ0DIARBAXQhBCACIQMgAkEEaigCAEF4cSABRw0ACwsgAigCCCIBIAA2AgwgAiAANgIIIABBGGpBADYCACAAIAI2AgwgACABNgIICw8LIAUgADYCAAsgAEEYaiADNgIAIAAgADYCDCAAIAA2AggPCyABQQN2IgJBA3RB7KHAAGohAQJ/QeShwAAoAgAiA0EBIAJ0IgJxBEAgASgCCAwBC0HkocAAIAIgA3I2AgAgAQshAiABIAA2AgggAiAANgIMIAAgATYCDCAAIAI2AggL1AYBBH8jAEHQAWsiAiQAIAJBygBqQgA3AQAgAkHSAGpBADsBACACQdQAakIANwIAIAJB3ABqQgA3AgAgAkHkAGpCADcCACACQewAakIANwIAIAJB9ABqQgA3AgAgAkH8AGpBADoAACACQf0AakEANgAAIAJBgQFqQQA7AAAgAkGDAWpBADoAACACQQA7AUQgAkEANgFGIAJBwAA2AkAgAkGIAWogAkFAa0HEABCLARogAkE4aiACQcQBaikCADcDACACQTBqIAJBvAFqKQIANwMAIAJBKGogAkG0AWopAgA3AwAgAkEgaiACQawBaikCADcDACACQRhqIAJBpAFqKQIANwMAIAJBEGogAkGcAWopAgA3AwAgAkEIaiACQZQBaikCADcDACACIAIpAowBNwMAIAEgAhARIAFCADcDCCABQgA3AwAgAUEANgJQIAFBkJnAACkDADcDECABQRhqQZiZwAApAwA3AwAgAUEgakGgmcAAKQMANwMAIAFBKGpBqJnAACkDADcDACABQTBqQbCZwAApAwA3AwAgAUE4akG4mcAAKQMANwMAIAFBQGtBwJnAACkDADcDACABQcgAakHImcAAKQMANwMAAkACQEHAAEEBEKEBIgMEQCACQsAANwKMASACIAM2AogBIAJBiAFqIAJBwAAQXgJAIAIoAowBIgQgAigCkAEiA0YEQCAEIQMMAQsgBCADSQ0CIARFDQAgAigCiAEhBQJAIANFBEAgBRAQQQEhBAwBCyAFIARBASADEJoBIgRFDQQLIAIgAzYCjAEgAiAENgKIAQsgAigCiAEhBCABQgA3AwggAUIANwMAIAFBADYCUCABQRBqIgFBkJnAACkDADcDACABQQhqQZiZwAApAwA3AwAgAUEQakGgmcAAKQMANwMAIAFBGGpBqJnAACkDADcDACABQSBqQbCZwAApAwA3AwAgAUEoakG4mcAAKQMANwMAIAFBMGpBwJnAACkDADcDACABQThqQciZwAApAwA3AwAgACADNgIEIAAgBDYCACACQdABaiQADwtBwABBAUG0pcAAKAIAIgBBAiAAGxEAAAALQYeMwABBJEGsjMAAEIgBAAsgA0EBQbSlwAAoAgAiAEECIAAbEQAAAAuOBgEKfyMAQTBrIgIkACACQSRqQYCHwAA2AgAgAkEDOgAoIAJCgICAgIAENwMIIAIgADYCICACQQA2AhggAkEANgIQAn8CQAJAAkAgASgCCCIDBEAgASgCACEFIAEoAgQiCCABQQxqKAIAIgYgBiAISxsiBkUNASABQRRqKAIAIQcgASgCECEJIAAgBSgCACAFKAIEQYyHwAAoAgARAwANAyAFQQhqIQECQAJAA0AgAiADQQRqKAIANgIMIAIgA0Ecai0AADoAKCACIANBCGooAgA2AgggA0EYaigCACEAQQAhBAJAAkACQCADQRRqKAIAQQFrDgIAAgELIAAgB08NAyAAQQN0IAlqIgooAgRBA0cNASAKKAIAKAIAIQALQQEhBAsgAiAANgIUIAIgBDYCECADQRBqKAIAIQBBACEEAkACQAJAIANBDGooAgBBAWsOAgACAQsgACAHTw0EIABBA3QgCWoiCigCBEEDRw0BIAooAgAoAgAh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IQEgACgCGCEAA0AgBkF/aiIGRQRAQQAPCyAAIAcgASgCEBEBAEUNAAsLIAULtwUBBH8jAEGQAWsiAiQAIAJBOmpCADcBACACQcIAakEAOwEAIAJBxABqQgA3AgAgAkHMAGpCADcCACACQdQAakIANwIAIAJBADsBNCACQQA2ATYgAkEoNgIwIAJBgAFqIAJB0ABqKQMANwMAIAJB+ABqIAJByABqKQMANwMAIAJB8ABqIAJBQGspAwA3AwAgAkHoAGogAkE4aikDADcDACACQYgBaiACQdgAaigCADYCACACIAIpAzA3A2AgAkEgaiACQfwAaikCADcDACACQRhqIAJB9ABqKQIANwMAIAJBEGogAkHsAGopAgA3AwAgAkEoaiACQYQBaikCADcDACACIAIpAmQ3AwggASACQQhqEE0gAUIANwMAIAFBADYCMCABQdCXwAApAwA3AwggAUEQakHYl8AAKQMANwMAIAFBGGpB4JfAACkDADcDACABQSBqQeiXwAApAwA3AwAgAUEoakHwl8AAKQMANwMAAkACQEEoQQEQoQEiAwRAIAJCKDcCZCACIAM2AmAgAkHgAGogAkEIakEoEF4CQCACKAJkIgQgAigCaCIDRgRAIAQhAwwBCyAEIANJDQIgBEUNACACKAJgIQUCQCADRQRAIAUQEEEBIQQMAQsgBSAEQQEgAxCaASIERQ0ECyACIAM2AmQgAiAENgJgCyACKAJgIQQgAUIANwMAIAFBADYCMCABQQhqIgFB0JfAACkDADcDACABQQhqQdiXwAApAwA3AwAgAUEQakHgl8AAKQMANwMAIAFBGGpB6JfAACkDADcDACABQSBqQfCXwAApAwA3AwAgACADNgIEIAAgBDYCACACQZABaiQADwtBKEEBQbSlwAAoAgAiAEECIAAbEQAAAAtBh4zAAEEkQayMwAAQiAEACyADQQFBtKXAACgCACIAQQIgABsRAAAAC8YEAQR/IwBBoAFrIgIkACACQTpqQgA3AQAgAkHCAGpBADsBACACQcQAakIANwIAIAJBzABqQgA3AgAgAkHUAGpCADcCACACQdwAakIANwIAIAJBADsBNCACQQA2ATYgAkEwNgIwIAJBkAFqIAJB2ABqKQMANwMAIAJBiAFqIAJB0ABqKQMANwMAIAJBgAFqIAJByABqKQMANwMAIAJB+ABqIAJBQGspAwA3AwAgAkHwAGogAkE4aikDADcDACACQZgBaiACQeAAaigCADYCACACIAIpAzA3A2ggAkEgaiACQYwBaikCADcDACACQRhqIAJBhAFqKQIANwMAIAJBEGogAkH8AGopAgA3AwAgAkEIaiACQfQAaikCADcDACACQShqIAJBlAFqKQIANwMAIAIgAikCbDcDACABIAIQYyABQQBByAEQkQEiBUEANgLIAQJAAkBBMEEBEKEBIgEEQCACQjA3AmwgAiABNgJoIAJB6ABqIAJBMBBeAkAgAigCbCIDIAIoAnAiAUYEQCADIQEMAQsgAyABSQ0CIANFDQAgAigCaCEEAkAgAUUEQCAEEBBBASEDDAELIAQgA0EBIAEQmgEiA0UNBAsgAiABNgJsIAIgAzYCaAsgAigCaCEDIAVBAEHIARCRAUEANgLIASAAIAE2AgQgACADNgIAIAJBoAFqJAAPC0EwQQFBtKXAACgCACIAQQIgABsRAAAAC0GHjMAAQSRBrIzAABCIAQALIAFBAUG0pcAAKAIAIgBBAiAAGxEAAAALxgQBBH8jAEGgAWsiAiQAIAJBOmpCADcBACACQcIAakEAOwEAIAJBxABqQgA3AgAgAkHMAGpCADcCACACQdQAakIANwIAIAJB3ABqQgA3AgAgAkEAOwE0IAJBADYBNiACQTA2AjAgAkGQAWogAkHYAGopAwA3AwAgAkGIAWogAkHQAGopAwA3AwAgAkGAAWogAkHIAGopAwA3AwAgAkH4AGogAkFAaykDADcDACACQfAAaiACQThqKQMANwMAIAJBmAFqIAJB4ABqKAIANgIAIAIgAikDMDcDaCACQSBqIAJBjAFqKQIANwMAIAJBGGogAkGEAWopAgA3AwAgAkEQaiACQfwAaikCADcDACACQQhqIAJB9ABqKQIANwMAIAJBKGogAkGUAWopAgA3AwAgAiACKQJsNwMAIAEgAhBkIAFBAEHIARCRASIFQQA2AsgBAkACQEEwQQEQoQEiAQRAIAJCMDcCbCACIAE2AmggAkHoAGogAkEwEF4CQCACKAJsIgMgAigCcCIBRgRAIAMhAQwBCyADIAFJDQIgA0UNACACKAJoIQQCQCABRQRAIAQQEEEBIQMMAQsgBCADQQEgARCaASIDRQ0ECyACIAE2AmwgAiADNgJoCyACKAJoIQMgBUEAQcgBEJEBQQA2AsgBIAAgATYCBCAAIAM2AgAgAkGgAWokAA8LQTBBAUG0pcAAKAIAIgBBAiAAGxEAAAALQYeMwABBJEGsjMAAEIgBAAsgAUEBQbSlwAAoAgAiAEECIAAbEQAAAAu8BAEEfyMAQaADayICJAAgAkHyAmpCADcBACACQfoCakEAOwEAIAJB/AJqQgA3AgAgAkGEA2pCADcCACACQYwDakIANwIAIAJBlANqQgA3AgAgAkEAOwHsAiACQQA2Ae4CIAJBMDYC6AIgAkHYAGogAkGQA2opAwA3AwAgAkHQAGogAkGIA2opAwA3AwAgAkHIAGogAkGAA2opAwA3AwAgAkFAayACQfgCaikDADcDACACQThqIAJB8AJqKQMANwMAIAJB4ABqIAJBmANqKAIANgIAIAIgAikD6AI3AzAgAkEgaiACQdQAaikCADcDACACQRhqIAJBzABqKQIANwMAIAJBEGogAkHEAGopAgA3AwAgAkEIaiACQTxqKQIANwMAIAJBKGogAkHcAGopAgA3AwAgAiACKQI0NwMAIAJBMGogAUG4AhCLARogAkEwaiACEGMCQAJAQTBBARChASIDBEAgAkIwNwI0IAIgAzYCMCACQTBqIAJBMBBeAkAgAigCNCIEIAIoAjgiA0YEQCAEIQMMAQsgBCADSQ0CIARFDQAgAigCMCEFAkAgA0UEQCAFEBBBASEEDAELIAUgBEEBIAMQmgEiBEUNBAsgAiADNgI0IAIgBDYCMAsgAigCMCEEIAEQECAAIAM2AgQgACAENgIAIAJBoANqJAAPC0EwQQFBtKXAACgCACIAQQIgABsRAAAAC0GHjMAAQSRBrIzAABCIAQALIANBAUG0pcAAKAIAIgBBAiAAGxEAAAALvAQBBH8jAEGgA2siAiQAIAJB8gJqQgA3AQAgAkH6AmpBADsBACACQfwCakIANwIAIAJBhANqQgA3AgAgAkGMA2pCADcCACACQZQDakIANwIAIAJBADsB7AIgAkEANgHuAiACQTA2AugCIAJB2ABqIAJBkANqKQMANwMAIAJB0ABqIAJBiANqKQMANwMAIAJByABqIAJBgANqKQMANwMAIAJBQGsgAkH4AmopAwA3AwAgAkE4aiACQfACaikDADcDACACQeAAaiACQZgDaigCADYCACACIAIpA+gCNwMwIAJBIGogAkHUAGopAgA3AwAgAkEYaiACQcwAaikCADcDACACQRBqIAJBxABqKQIANwMAIAJBCGogAkE8aikCADcDACACQShqIAJB3ABqKQIANwMAIAIgAikCNDcDACACQTBqIAFBuAIQiwEaIAJBMGogAhBkAkACQEEwQQEQoQEiAwRAIAJCMDcCNCACIAM2AjAgAkEwaiACQTAQXgJAIAIoAjQiBCACKAI4IgNGBEAgBCEDDAELIAQgA0kNAiAERQ0AIAIoAjAhBQJAIANFBEAgBRAQQQEhBAwBCyAFIARBASADEJoBIgRFDQQLIAIgAzYCNCACIAQ2AjALIAIoAjAhBCABEBAgACADNgIEIAAgBDYCACACQaADaiQADwtBMEEBQbSlwAAoAgAiAEECIAAbEQAAAAtBh4zAAEEkQayMwAAQiAEACyADQQFBtKXAACgCACIAQQIgABsRAAAAC7wEAQR/IwBBwAJrIgIkACACQZICakIANwEAIAJBmgJqQQA7AQAgAkGcAmpCADcCACACQaQCakIANwIAIAJBrAJqQgA3AgAgAkG0AmpCADcCACACQQA7AYwCIAJBADYBjgIgAkEwNgKIAiACQdgAaiACQbACaikDADcDACACQdAAaiACQagCaikDADcDACACQcgAaiACQaACaikDADcDACACQUBrIAJBmAJqKQMANwMAIAJBOGogAkGQAmopAwA3AwAgAkHgAGogAkG4AmooAgA2AgAgAiACKQOIAjcDMCACQSBqIAJB1ABqKQIANwMAIAJBGGogAkHMAGopAgA3AwAgAkEQaiACQcQAaikCADcDACACQQhqIAJBPGopAgA3AwAgAkEoaiACQdwAaikCADcDACACIAIpAjQ3AwAgAkEwaiABQdgBEIsBGiACQTBqIAIQHwJAAkBBMEEBEKEBIgMEQCACQjA3AjQgAiADNgIwIAJBMGogAkEwEF4CQCACKAI0IgQgAigCOCIDRgRAIAQhAwwBCyAEIANJDQIgBEUNACACKAIwIQUCQCADRQRAIAUQEEEBIQQMAQsgBSAEQQEgAxCaASIERQ0ECyACIAM2AjQgAiAENgIwCyACKAIwIQQgARAQIAAgAzYCBCAAIAQ2AgAgAkHAAmokAA8LQTBBAUG0pcAAKAIAIgBBAiAAGxEAAAALQYeMwABBJEGs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AkHwAGokAA8LQSBBAUG0pcAAKAIAIgBBAiAAGxEAAAALQYeMwABBJEGsjMAAEIgBAAsgA0EBQbSlwAAoAgAiAEECIAAbEQAAAAvMBAEEfyMAQdABayICJAAgAkHKAGpCADcBACACQdIAakEAOwEAIAJB1ABqQgA3AgAgAkHcAGpCADcCACACQeQAakIANwIAIAJB7ABqQgA3AgAgAkH0AGpCADcCACACQfwAakEAOgAAIAJB/QBqQQA2AAAgAkGBAWpBADsAACACQYMBakEAOgAAIAJBADsBRCACQQA2AUYgAkHAADYCQCACQYgBaiACQUBrQcQAEIsBGiACQThqIAJBxAFqKQIANwMAIAJBMGogAkG8AWopAgA3AwAgAkEoaiACQbQBaikCADcDACACQSBqIAJBrAFqKQIANwMAIAJBGGogAkGkAWopAgA3AwAgAkEQaiACQZwBaikCADcDACACQQhqIAJBlAFqKQIANwMAIAIgAikCjAE3AwAgASACEFsgAUEAQcgBEJEBIgVBADYCyAECQAJAQcAAQQEQoQEiAQRAIAJCwAA3AowBIAIgATYCiAEgAkGIAWogAkHAABBeAkAgAigCjAEiAyACKAKQASIBRgRAIAMhAQwBCyADIAFJDQIgA0UNACACKAKIASEEAkAgAUUEQCAEEBBBASEDDAELIAQgA0EBIAEQmgEiA0UNBAsgAiABNgKMASACIAM2AogBCyACKAKIASEDIAVBAEHIARCRAUEANgLIASAAIAE2AgQgACADNgIAIAJB0AFqJAAPC0HAAEEBQbSlwAAoAgAiAEECIAAbEQAAAAtBh4zAAEEkQayMwAAQiAEACyABQQFBtKXAACgCACIAQQIgABsRAAAAC8wEAQR/IwBB0AFrIgIkACACQcoAakIANwEAIAJB0gBqQQA7AQAgAkHUAGpCADcCACACQdwAakIANwIAIAJB5ABqQgA3AgAgAkHsAGpCADcCACACQfQAakIANwIAIAJB/ABqQQA6AAAgAkH9AGpBADYAACACQYEBakEAOwAAIAJBgwFqQQA6AAAgAkEAOwFEIAJBADYBRiACQcAANgJAIAJBiAFqIAJBQGtBxAAQiwEaIAJBOGogAkHEAWopAgA3AwAgAkEwaiACQbwBaikCADcDACACQShqIAJBtAFqKQIANwMAIAJBIGogAkGsAWopAgA3AwAgAkEYaiACQaQBaikCADcDACACQRBqIAJBnAFqKQIANwMAIAJBCGogAkGUAWopAgA3AwAgAiACKQKMATcDACABIAIQXCABQQBByAEQkQEiBUEANgLIAQJAAkBBwABBARChASIBBEAgAkLAADcCjAEgAiABNgKIASACQYgBaiACQcAAEF4CQCACKAKMASIDIAIoApABIgFGBEAgAyEBDAELIAMgAUkNAiADRQ0AIAIoAogBIQQCQCABRQRAIAQQEEEBIQMMAQsgBCADQQEgARCaASIDRQ0ECyACIAE2AowBIAIgAzYCiAELIAIoAogBIQMgBUEAQcgBEJEBQQA2AsgBIAAgATYCBCAAIAM2AgAgAkHQAWokAA8LQcAAQQFBtKXAACgCACIAQQIgABsRAAAAC0GHjMAAQSRBrIzAABCIAQALIAFBAUG0pcAAKAIAIgBBAiAAGxEAAAALuAQBBH8jAEGgA2siAiQAIAJB4gJqQgA3AQAgAkHqAmpBADsBACACQewCakIANwIAIAJB9AJqQgA3AgAgAkH8AmpCADcCACACQYQDakIANwIAIAJBjANqQgA3AgAgAkGUA2pBADoAACACQZUDakEANgAAIAJBmQNqQQA7AAAgAkGbA2pBADoAACACQQA7AdwCIAJBADYB3gIgAkHAADYC2AIgAkFAayACQdgCakHEABCLARogAkE4aiACQfwAaikCADcDACACQTBqIAJB9ABqKQIANwMAIAJBKGogAkHsAGopAgA3AwAgAkEgaiACQeQAaikCADcDACACQRhqIAJB3ABqKQIANwMAIAJBEGogAkHUAGopAgA3AwAgAkEIaiACQcwAaikCADcDACACIAIpAkQ3AwAgAkFAayABQZgCEIsBGiACQUBrIAIQWwJAAkBBwABBARChASIDBEAgAkLAADcCRCACIAM2AkAgAkFAayACQcAAEF4CQCACKAJEIgQgAigCSCIDRgRAIAQhAwwBCyAEIANJDQIgBEUNACACKAJAIQUCQCADRQRAIAUQEEEBIQQMAQsgBSAEQQEgAxCaASIERQ0ECyACIAM2AkQgAiAENgJACyACKAJAIQQgARAQIAAgAzYCBCAAIAQ2AgAgAkGgA2okAA8LQcAAQQFBtKXAACgCACIAQQIgABsRAAAAC0GHjMAAQSRBrIzAABCIAQALIANBAUG0pcAAKAIAIgBBAiAAGxEAAAALuAQBBH8jAEGgA2siAiQAIAJB4gJqQgA3AQAgAkHqAmpBADsBACACQewCakIANwIAIAJB9AJqQgA3AgAgAkH8AmpCADcCACACQYQDakIANwIAIAJBjANqQgA3AgAgAkGUA2pBADoAACACQZUDakEANgAAIAJBmQNqQQA7AAAgAkGbA2pBADoAACACQQA7AdwCIAJBADYB3gIgAkHAADYC2AIgAkFAayACQdgCakHEABCLARogAkE4aiACQfwAaikCADcDACACQTBqIAJB9ABqKQIANwMAIAJBKGogAkHsAGopAgA3AwAgAkEgaiACQeQAaikCADcDACACQRhqIAJB3ABqKQIANwMAIAJBEGogAkHUAGopAgA3AwAgAkEIaiACQcwAaikCADcDACACIAIpAkQ3AwAgAkFAayABQZgCEIsBGiACQUBrIAIQXAJAAkBBwABBARChASIDBEAgAkLAADcCRCACIAM2AkAgAkFAayACQcAAEF4CQCACKAJEIgQgAigCSCIDRgRAIAQhAwwBCyAEIANJDQIgBEUNACACKAJAIQUCQCADRQRAIAUQEEEBIQQMAQsgBSAEQQEgAxCaASIERQ0ECyACIAM2AkQgAiAENgJACyACKAJAIQQgARAQIAAgAzYCBCAAIAQ2AgAgAkGgA2okAA8LQcAAQQFBtKXAACgCACIAQQIgABsRAAAAC0GHjMAAQSRBrIzAABCIAQALIANBAUG0pcAAKAIAIgBBAiAAGxEAAAALuAQBBH8jAEHgAmsiAiQAIAJBogJqQgA3AQAgAkGqAmpBADsBACACQawCakIANwIAIAJBtAJqQgA3AgAgAkG8AmpCADcCACACQcQCakIANwIAIAJBzAJqQgA3AgAgAkHUAmpBADoAACACQdUCakEANgAAIAJB2QJqQQA7AAAgAkHbAmpBADoAACACQQA7AZwCIAJBADYBngIgAkHAADYCmAIgAkFAayACQZgCakHEABCLARogAkE4aiACQfwAaikCADcDACACQTBqIAJB9ABqKQIANwMAIAJBKGogAkHsAGopAgA3AwAgAkEgaiACQeQAaikCADcDACACQRhqIAJB3ABqKQIANwMAIAJBEGogAkHUAGopAgA3AwAgAkEIaiACQcwAaikCADcDACACIAIpAkQ3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AABzOgAAIAVBAWoiBUHIAEcNAAsgABAOIAZByABJDQJByAAhBSACQcgAaiECIAhByABqIQgMAAsACyACIARqIgYgBEkNAiAGQcgASw0DIAAgBGpBzAFqIAEgAhCLARogACgCyAEgAmohBwwBCyAAQcwBaiABIARqIAcQiwEaCyAAIAc2AsgBIANBQGskAA8LIAQgBkHAm8AAEH4ACyAGQcgAQcCbwAAQfQALIARByABB0JvAABB+AAsgBCACQeCbwAAQfQALIANBNGpBBjYCACADQSRqQQI2AgAgA0IDNwIUIANBuJ7AADYCECADQQY2AiwgAyADQQxqNgI4IANB3J7AADYCPCADIANBKGo2AiAgAyADQTxqNgIwIAMgA0E4ajYCKCADQRBqQeCewAAQkAEAC5sEAQd/IwBBQGoiAyQAAkACQAJAAkACQAJAAkBB6AAgACgCyAEiBGsiBiACTQRAIAQEQCAEQekATw0GIAAgBGpBzAFqIAEgBhCLARogAiAGayECIAEgBmohAQNAIAAgBWoiBCAELQAAIARBzAFqLQAAczoAACAFQQFqIgVB6ABHDQALIAAQDgsgAiACQegAcCIHayEEIAIgB0kNBiAEQegASQ0BIAFB6ABqIQggASECIAQhBkHoACEFA0AgAyAFNgIMIAVB6ABHDQggBkGYf2ohBkEAIQUDQCAAIAVqIgkgCS0AACACIAVqLQAAczoAACAFQQFqIgVB6ABHDQALIAAQDiAGQegASQ0CQegAIQUgAkHoAGohAiAIQegAaiEIDAALAAsgAiAEaiIGIARJDQIgBkHoAEsNAyAAIARqQcwBaiABIAIQiwEaIAAoAsgBIAJqIQcMAQsgAEHMAWogASAEaiAHEIsBGgsgACAHNgLIASADQUBrJAAPCyAEIAZBwJvAABB+AAsgBkHoAEHAm8AAEH0ACyAEQegAQdCbwAAQfgALIAQgAkHgm8AAEH0ACyADQTRqQQY2AgAgA0EkakECNgIAIANCAzcCFCADQbiewAA2AhAgA0EGNgIsIAMgA0EMajYCOCADQdiewAA2AjwgAyADQShqNgIgIAMgA0E8ajYCMCADIANBOGo2AiggA0EQakHgnsAAEJABAAvkAwEEfyMAQcABayICJAAgAkGiAWpCADcBACACQaoBakEAOwEAIAJBrAFqQgA3AgAgAkG0AWpCADcCACACQQA7AZwBIAJBADYBngEgAkEgNgKYASACQUBrIAJBsAFqKQMANwMAIAJBOGogAkGoAWopAwA3AwAgAkEwaiACQaABaikDADcDACACQcgAaiACQbgBaigCADYCACACIAIpA5gBNwMoIAJBGGogAkE8aikCADcDACACQRBqIAJBNGopAgA3AwAgAkEgaiACQcQAaikCADcDACACIAIpAiw3AwggAkEoaiABQfAAEIsBGiACQShqIAJBCGoQOwJAAkBBIEEBEKEBIgMEQCACQiA3AiwgAiADNgIoIAJBKGogAkEIakEgEF4CQCACKAIsIgQgAigCMCIDRgRAIAQhAwwBCyAEIANJDQIgBEUNACACKAIoIQUCQCADRQRAIAUQEEEBIQQMAQsgBSAEQQEgAxCaASIERQ0ECyACIAM2AiwgAiAENgIoCyACKAIoIQQgARAQIAAgAzYCBCAAIAQ2AgAgAkHAAWokAA8LQSBBAUG0pcAAKAIAIgBBAiAAGxEAAAALQYeMwABBJEGsjMAAEIgBAAsgA0EBQbSlwAAoAgAiAEECIAAbEQAAAAuOBAEFfyMAQYABayICJAAgAkHyAGpCADcBACACQfoAakEAOwEAIAJBADsBbCACQQA2AW4gAkEQNgJoIAJBGGogAkHwAGoiBCkDADcDACACQSBqIAJB+ABqKAIANgIAIAJBCGoiBSACQRxqKQIANwMAIAIgAikDaDcDECACIAIpAhQ3AwAgAkEQaiABQdQAEIsBGgJAAkACQCACKAIQIgNBEEkEQCACQRBqQQRyIgYgA2pBECADayIDIAMQkQEaIAJBADYCECACQSRqIgMgBhALIAQgAkHcAGopAgA3AwAgAiACQdQAaikCADcDaCADIAJB6ABqEAsgBSACQSxqKQIANwMAIAIgAikCJDcDAEEQQQEQoQEiA0UNASACQhA3AhQgAiADNgIQIAJBEGogAkEQEF4CQCACKAIUIgQgAigCGCIDRgRAIAQhAwwBCyAEIANJDQMgBEUNACACKAIQIQUCQCADRQRAIAUQEEEBIQQMAQsgBSAEQQEgAxCaASIERQ0FCyACIAM2AhQgAiAENgIQCyACKAIQIQQgARAQIAAgAzYCBCAAIAQ2AgAgAkGAAWokAA8LQbCawABBFyACQegAakGgl8AAQbCXwAAQeQALQRBBAUG0pcAAKAIAIgBBAiAAGxEAAAALQYeMwABBJEGsjMAAEIgBAAsgA0EBQbSlwAAoAgAiAEECIAAbEQAAAAuFBAEEfyMAQdAAayICJAAgAkEqakIANwEAIAJBMmpBADsBACACQRQ2AiAgAkE0akEANgIAIAJBADsBJCACQQA2ASYgAkHIAGogAkEwaikDADcDACACQUBrIAJBKGopAwA3AwAgAkEQaiACQcQAaikCADcDACACQRhqIAJBzABqKAIANgIAIAIgAikDIDcDOCACIAIpAjw3AwggASACQQhqEFogAUIANwMAIAFBADYCHCABQfiXwAApAwA3AwggAUEQakGAmMAAKQMANwMAIAFBGGpBiJjAACgCADYCAAJAAkBBFEEBEKEBIgMEQCACQhQ3AjwgAiADNgI4IAJBOGogAkEIakEUEF4CQCACKAI8IgQgAigCQCIDRgRAIAQhAwwBCyAEIANJDQIgBEUNACACKAI4IQUCQCADRQRAIAUQEEEBIQQMAQsgBSAEQQEgAxCaASIERQ0ECyACIAM2AjwgAiAENgI4CyACKAI4IQQgAUIANwMAIAFBADYCHCABQQhqIgFB+JfAACkDADcDACABQQhqQYCYwAApAwA3AwAgAUEQakGImMAAKAIANgIAIAAgAzYCBCAAIAQ2AgAgAkHQAGokAA8LQRRBAUG0pcAAKAIAIgBBAiAAGxEAAAALQYeMwABBJEGsjMAAEIgBAAsgA0EBQbSlwAAoAgAiAEECIAAbEQAAAAuFBAEEfyMAQdAAayICJAAgAkEqakIANwEAIAJBMmpBADsBACACQRQ2AiAgAkE0akEANgIAIAJBADsBJCACQQA2ASYgAkHIAGogAkEwaikDADcDACACQUBrIAJBKGopAwA3AwAgAkEQaiACQcQAaikCADcDACACQRhqIAJBzABqKAIANgIAIAIgAikDIDcDOCACIAIpAjw3AwggASACQQhqECAgAUEANgIcIAFCADcDACABQRhqQYiYwAAoAgA2AgAgAUEQakGAmMAAKQMANwMAIAFB+JfAACkDADcDCAJAAkBBFEEBEKEBIgMEQCACQhQ3AjwgAiADNgI4IAJBOGogAkEIakEUEF4CQCACKAI8IgQgAigCQCIDRgRAIAQhAwwBCyAEIANJDQIgBEUNACACKAI4IQUCQCADRQRAIAUQEEEBIQQMAQsgBSAEQQEgAxCaASIERQ0ECyACIAM2AjwgAiAENgI4CyACKAI4IQQgAUEANgIcIAFCADcDACABQQhqIgFBEGpBiJjAACgCADYCACABQQhqQYCYwAApAwA3AwAgAUH4l8AAKQMANwMAIAAgAzYCBCAAIAQ2AgAgAkHQAGokAA8LQRRBAUG0pcAAKAIAIgBBAiAAGxEAAAALQYeMwABBJEGsjMAAEIgBAAsgA0EBQbSlwAAoAgAiAEECIAAbEQAAAAvlAwEEfyMAQfAAayICJAAgAkEqakIANwEAIAJBMmpBADsBACACQTRqQgA3AgAgAkE8akIANwIAIAJBADsBJCACQQA2ASYgAkEgNgIgIAJB4ABqIAJBOGopAwA3AwAgAkHYAGogAkEwaikDADcDACACQdAAaiACQShqKQMANwMAIAJB6ABqIAJBQGsoAgA2AgAgAiACKQMgNwNIIAJBEGogAkHcAGopAgA3AwAgAkEIaiACQdQAaikCADcDACACQRhqIAJB5ABqKQIANwMAIAIgAikCTDcDACABIAIQZiABQQBByAEQkQEiBUEANgLIAQJAAkBBIEEBEKEBIgEEQCACQiA3AkwgAiABNgJIIAJByABqIAJBIBBeAkAgAigCTCIDIAIoAlAiAUYEQCADIQEMAQsgAyABSQ0CIANFDQAgAigCSCEEAkAgAUUEQCAEEBBBASEDDAELIAQgA0EBIAEQmgEiA0UNBAsgAiABNgJMIAIgAzYCSAsgAigCSCEDIAVBAEHIARCRAUEANgLIASAAIAE2AgQgACADNgIAIAJB8ABqJAAPC0EgQQFBtKXAACgCACIAQQIgABsRAAAAC0GHjMAAQSRBrIzAABCIAQALIAFBAUG0pcAAKAIAIgBBAiAAGxEAAAAL5QMBBH8jAEHwAGsiAiQAIAJBKmpCADcBACACQTJqQQA7AQAgAkE0akIANwIAIAJBPGpCADcCACACQQA7ASQgAkEANgEmIAJBIDYCICACQeAAaiACQThqKQMANwMAIAJB2ABqIAJBMGopAwA3AwAgAkHQAGogAkEoaikDADcDACACQegAaiACQUBrKAIANgIAIAIgAikDIDcDSCACQRBqIAJB3ABqKQIANwMAIAJBCGogAkHUAGopAgA3AwAgAkEYaiACQeQAaikCADcDACACIAIpAkw3AwAgASACEGcgAUEAQcgBEJEBIgVBADYCyAECQAJAQSBBARChASIBBEAgAkIgNwJMIAIgATYCSCACQcgAaiACQSAQXgJAIAIoAkwiAyACKAJQIgFGBEAgAyEBDAELIAMgAUkNAiADRQ0AIAIoAkghBAJAIAFFBEAgBBAQQQEhAwwBCyAEIANBASABEJoBIgNFDQQLIAIgATYCTCACIAM2AkgLIAIoAkghAyAFQQBByAEQkQFBADYCyAEgACABNgIEIAAgAzYCACACQfAAaiQADwtBIEEBQbSlwAAoAgAiAEECIAAbEQAAAAtBh4zAAEEkQayMwAAQiAEACyABQQFBtKXAACgCACIAQQIgABsRAAAAC9wDAQR/IwBBoANrIgIkACACQYIDakIANwEAIAJBigNqQQA7AQAgAkGMA2pCADcCACACQZQDakIANwIAIAJBADsB/AIgAkEANgH+AiACQSA2AvgCIAJBOGogAkGQA2opAwA3AwAgAkEwaiACQYgDaikDADcDACACQShqIAJBgANqKQMANwMAIAJBQGsgAkGYA2ooAgA2AgAgAiACKQP4AjcDICACQRBqIAJBNGopAgA3AwAgAkEIaiACQSxqKQIANwMAIAJBGGogAkE8aikCADcDACACIAIpAiQ3AwAgAkEgaiABQdgCEIsBGiACQSBqIAIQZgJAAkBBIEEBEKEBIgMEQCACQiA3AiQgAiADNgIgIAJBIGogAkEgEF4CQCACKAIkIgQgAigCKCIDRgRAIAQhAwwBCyAEIANJDQIgBEUNACACKAIgIQUCQCADRQRAIAUQEEEBIQQMAQsgBSAEQQEgAxCaASIERQ0ECyACIAM2AiQgAiAENgIgCyACKAIgIQQgARAQIAAgAzYCBCAAIAQ2AgAgAkGgA2okAA8LQSBBAUG0pcAAKAIAIgBBAiAAGxEAAAALQYeMwABBJEGsjMAAEIgBAAsgA0EBQbSlwAAoAgAiAEECIAAbEQAAAAvcAwEEfyMAQaADayICJAAgAkGCA2pCADcBACACQYoDakEAOwEAIAJBjANqQgA3AgAgAkGUA2pCADcCACACQQA7AfwCIAJBADYB/gIgAkEgNgL4AiACQThqIAJBkANqKQMANwMAIAJBMGogAkGIA2opAwA3AwAgAkEoaiACQYADaikDADcDACACQUBrIAJBmANqKAIANgIAIAIgAikD+AI3AyAgAkEQaiACQTRqKQIANwMAIAJBCGogAkEsaikCADcDACACQRhqIAJBPGopAgA3AwAgAiACKQIkNwMAIAJBIGogAUHYAhCLARogAkEgaiACEGcCQAJAQSBBARChASIDBEAgAkIgNwIkIAIgAzYCICACQSBqIAJBIBBeAkAgAigCJCIEIAIoAigiA0YEQCAEIQMMAQsgBCADSQ0CIARFDQAgAigCICEFAkAgA0UEQCAFEBBBASEEDAELIAUgBEEBIAMQmgEiBEUNBAsgAiADNgIkIAIgBDYCIAsgAigCICEEIAEQECAAIAM2AgQgACAENgIAIAJBoANqJAAPC0EgQQFBtKXAACgCACIAQQIgABsRAAAAC0GHjMAAQSRBrIzAABCIAQALIANBAUG0pcAAKAIAIgBBAiAAGxEAAAAL0wMBBH8jAEHgAGsiAiQAIAJBKmpCADcBACACQTJqQQA7AQAgAkE0akIANwIAIAJBHDYCICACQTxqQQA2AgAgAkEAOwEkIAJBADYBJiACQdgAaiACQThqKQMANwMAIAJB0ABqIAJBMGopAwA3AwAgAkHIAGogAkEoaikDADcDACACIAIpAyA3A0AgAkEYaiACQdwAaigCADYCACACQRBqIAJB1ABqKQIANwMAIAJBCGogAkHMAGopAgA3AwAgAiACKQJENwMAIAEgAhBoIAFBAEHIARCRASIFQQA2AsgBAkACQEEcQQEQoQEiAQRAIAJCHDcCRCACIAE2AkAgAkFAayACQRwQXgJAIAIoAkQiAyACKAJIIgFGBEAgAyEBDAELIAMgAUkNAiADRQ0AIAIoAkAhBAJAIAFFBEAgBBAQQQEhAwwBCyAEIANBASABEJoBIgNFDQQLIAIgATYCRCACIAM2AkALIAIoAkAhAyAFQQBByAEQkQFBADYCyAEgACABNgIEIAAgAzYCACACQeAAaiQADwtBHEEBQbSlwAAoAgAiAEECIAAbEQAAAAtBh4zAAEEkQayMwAAQiAEACyABQQFBtKXAACgCACIAQQIgABsRAAAAC9MDAQR/IwBB4ABrIgIkACACQSpqQgA3AQAgAkEyakEAOwEAIAJBNGpCADcCACACQRw2AiAgAkE8akEANgIAIAJBADsBJCACQQA2ASYgAkHYAGogAkE4aikDADcDACACQdAAaiACQTBqKQMANwMAIAJByABqIAJBKGopAwA3AwAgAiACKQMgNwNAIAJBGGogAkHcAGooAgA2AgAgAkEQaiACQdQAaikCADcDACACQQhqIAJBzABqKQIANwMAIAIgAikCRDcDACABIAIQaSABQQBByAEQkQEiBUEANgLIAQJAAkBBHEEBEKEBIgEEQCACQhw3AkQgAiABNgJAIAJBQGsgAkEcEF4CQCACKAJEIgMgAigCSCIBRgRAIAMhAQwBCyADIAFJDQIgA0UNACACKAJAIQQCQCABRQRAIAQQEEEBIQMMAQsgBCADQQEgARCaASIDRQ0ECyACIAE2AkQgAiADNgJACyACKAJAIQMgBUEAQcgBEJEBQQA2AsgBIAAgATYCBCAAIAM2AgAgAkHgAGokAA8LQRxBAUG0pcAAKAIAIgBBAiAAGxEAAAALQYeMwABBJEGsjMAAEIgBAAsgAUEBQbSlwAAoAgAiAEECIAAbEQAAAAvkAwIJfwF+IwBBoAFrIgIkACACQUBrIAFBBGoQciABKAIAIQggAkH4AGoiAyABQTxqKQAANwMAIAJB8ABqIgQgAUE0aikAADcDACACQegAaiIFIAFBLGopAAA3AwAgAkHgAGoiBiABQSRqKQAANwMAIAJB2ABqIgcgAUEcaikAADcDACACIAEpABQ3A1AgAkGQAWogAUHEAGoQciACQQhqIgkgBykDADcDACACQRBqIgcgBikDADcDACACQRhqIgYgBSkDADcDACACQSBqIgUgBCkDADcDACACQShqIgQgAykDADcDACACQTBqIgMgAikDkAEiCzcDACACQThqIgogAkGYAWopAwA3AwAgAiALNwOAASACIAIpA1A3AwBB1ABBBBChASIBRQRAQdQAQQRBtKXAACgCACIAQQIgABsRAAAACyABIAg2AgAgASACKQNANwIEIAEgAikDADcCFCABQQxqIAJByABqKQMANwIAIAFBHGogCSkDADcCACABQSRqIAcpAwA3AgAgAUEsaiAGKQMANwIAIAFBNGogBSkDADcCACABQTxqIAQpAwA3AgAgAUHEAGogAykDADcCACABQcwAaiAKKQMANwIAIABB9I/AADYCBCAAIAE2AgAgAkGgAWokAAvLAwEEfyMAQaADayICJAAgAkGKA2pCADcBACACQZIDakEAOwEAIAJBlANqQgA3AgAgAkEcNgKAAyACQZwDakEANgIAIAJBADsBhAMgAkEANgGGAyACQThqIAJBmANqKQMANwMAIAJBMGogAkGQA2opAwA3AwAgAkEoaiACQYgDaikDADcDACACIAIpA4ADNwMgIAJBGGogAkE8aigCADYCACACQRBqIAJBNGopAgA3AwAgAkEIaiACQSxqKQIANwMAIAIgAikCJDcDACACQSBqIAFB4AIQiwEaIAJBIGogAhBpAkACQEEcQQEQoQEiAwRAIAJCHDcCJCACIAM2AiAgAkEgaiACQRwQXgJAIAIoAiQiBCACKAIoIgNGBEAgBCEDDAELIAQgA0kNAiAERQ0AIAIoAiAhBQJAIANFBEAgBRAQQQEhBAwBCyAFIARBASADEJoBIgRFDQQLIAIgAzYCJCACIAQ2AiALIAIoAiAhBCABEBAgACADNgIEIAAgBDYCACACQaADaiQADwtBHEEBQbSlwAAoAgAiAEECIAAbEQAAAAtBh4zAAEEkQayMwAAQiAEACyADQQFBtKXAACgCACIAQQIgABsRAAAAC8sDAQR/IwBBoANrIgIkACACQYoDakIANwEAIAJBkgNqQQA7AQAgAkGUA2pCADcCACACQRw2AoADIAJBnANqQQA2AgAgAkEAOwGEAyACQQA2AYYDIAJBOGogAkGYA2opAwA3AwAgAkEwaiACQZADaikDADcDACACQShqIAJBiANqKQMANwMAIAIgAikDgAM3AyAgAkEYaiACQTxqKAIANgIAIAJBEGogAkE0aikCADcDACACQQhqIAJBLGopAgA3AwAgAiACKQIkNwMAIAJBIGogAUHgAhCLARogAkEgaiACEGgCQAJAQRxBARChASIDBEAgAkIcNwIkIAIgAzYCICACQSBqIAJBHBBeAkAgAigCJCIEIAIoAigiA0YEQCAEIQMMAQsgBCADSQ0CIARFDQAgAigCICEFAkAgA0UEQCAFEBBBASEEDAELIAUgBEEBIAMQmgEiBEUNBAsgAiADNgIkIAIgBDYCIAsgAigCICEEIAEQECAAIAM2AgQgACAENgIAIAJBoANqJAAPC0EcQQFBtKXAACgCACIAQQIgABsRAAAAC0GHjMAAQSRBrIzAABCIAQALIANBAUG0pcAAKAIAIgBBAiAAGxEAAAALywMBBH8jAEGwAWsiAiQAIAJBmgFqQgA3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HCIEayIFIAJNBEAgAEEIaiEHIAQEQCAEQcEATw0GIAQgAEEgaiIEaiABIAUQiwEaIAcgBBAHIAIgBWshAiABIAVqIQELIAJBP3EhBSACQUBxIghBwABJDQEgAiAFa0FAaiEGIAEhBEHAACECA0AgAyACNgIMIAJBwABHDQcgByAEEAcgBkHAAEkNAiAEQUBrIQQgBkFAaiEGDAALAAsgAiAEaiIFIARJDQIgBUHAAEsNAyAAIARqQSBqIAEgAhCLARogACgCHCACaiEFDAELIABBIGogASAIaiAFEIsBGgsgACAFNgIcIANBQGskAA8LIAQgBUHAm8AAEH4ACyAFQcAAQcCbwAAQfQALIARBwABB0JvAABB+AAsgA0E0akEGNgIAIANBJGpBAjYCACADQgM3AhQgA0G4nsAANgIQIANBBjYCLCADIANBDGo2AjggA0GsjcAANgI8IAMgA0EoajYCICADIANBPGo2AjAgAyADQThqNgIoIANBEGpB4J7AABCQAQALtAMBBn8jAEFAaiIDJAAgACAAKQMAIAKtfDcDAAJAAkACQAJAAkACQEHAACAAKAIIIgRrIgUgAk0EQCAAQcwAaiEHIAQEQCAEQcEATw0GIAQgAEEMaiIEaiABIAUQiwEaIAcgBBAKIAIgBWshAiABIAVqIQELIAJBP3EhBSACQUBxIghBwABJDQEgAiAFa0FAaiEGIAEhBEHAACECA0AgAyACNgIMIAJBwABHDQcgByAEEAogBkHAAEkNAiAEQUBrIQQgBkFAaiEGDAALAAsgAiAEaiIFIARJDQIgBUHAAEsNAyAAIARqQQxqIAEgAhCLARogACgCCCACaiEFDAELIABBDGogASAIaiAFEIsBGgsgACAFNgIIIANBQGskAA8LIAQgBUHAm8AAEH4ACyAFQcAAQcCbwAAQfQALIARBwABB0JvAABB+AAsgA0E0akEGNgIAIANBJGpBAjYCACADQgM3AhQgA0G4nsAANgIQIANBBjYCLCADIANBDGo2AjggA0GsjcAANgI8IAMgA0EoajYCICADIANBPGo2AjAgAyADQThqNgIoIANBEGpB4J7AABCQAQAL0QMCBX8CfiAAQdQAaiECIABBEGohAyAAQQhqKQMAIQYgACkDACEHAkACQCAAKAJQIgFBgAFGBEAgAyACQQEQDEEAIQEgAEEA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AXFyQQJyNgIEIAAgA2oiAyADKAIEQQFyNgIEIAUgAiAFKAIAQQFxckECcjYCACAAIAAoAgRBAXI2AgQgASACEBQMAQsgASgCACEBIAAgAzYCBCAAIAEgAmo2AgALAkAgAEEEaigCACIBQQNxRQ0AIAFBeHEiAiAEQRBqTQ0AIABBBGogBCABQQFxckECcjYCACAAIARqIgEgAiAEayIEQQNyNgIEIAAgAmoiAiACKAIEQQFyNgIEIAEgBBAUCyAAQQhqIQMLIAMLiwMCBn8BfiMAQfAAayICJAAgAkHQAGoiAyABQRBqKQMANwMAIAJB2ABqIgQgAUEYaikDADcDACACQeAAaiIFIAFBIGopAwA3AwAgAkHoAGoiBiABQShqKQMANwMAIAIgASkDCDcDSCABKQMAIQggAkEIaiABQTRqEGUgASgCMCEHQfgAQQgQoQEiAUUEQEH4AEEIQbSlwAAoAgAiAEECIAAbEQAAAAsgASAINwMAIAEgAikDSDcDCCABIAc2AjAgASACKQMINwI0IAFBEGogAykDADcDACABQRhqIAQpAwA3AwAgAUEgaiAFKQMANwMAIAFBKGogBikDADcDACABQTxqIAJBEGopAwA3AgAgAUHEAGogAkEYaikDADcCACABQcwAaiACQSBqKQMANwIAIAFB1ABqIAJBKGopAwA3AgAgAUHcAGogAkEwaikDADcCACABQeQAaiACQThqKQMANwIAIAFB7ABqIAJBQGspAwA3AgAgAEHgjMAANgIEIAAgATYCACACQfAAaiQAC4YDAQR/IwBBkAFrIgIkACACQYIBakIANwEAIAJBigFqQQA7AQAgAkEAOwF8IAJBADYBfiACQRA2AnggAkEgaiACQYABaikDADcDACACQShqIAJBiAFqKAIANgIAIAJBEGogAkEkaikCADcDACACIAIpA3g3AxggAiACKQIcNwMIIAJBGGogAUHgABCLARogAkEYaiACQQhqEF0CQAJAQRBBARChASIDBEAgAkIQNwIcIAIgAzYCGCACQRhqIAJBCGpBEBBeAkAgAigCHCIEIAIoAiAiA0YEQCAEIQMMAQsgBCADSQ0CIARFDQAgAigCGCEFAkAgA0UEQCAFEBBBASEEDAELIAUgBEEBIAMQmgEiBEUNBAsgAiADNgIcIAIgBDYCGAsgAigCGCEEIAEQ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QT8gBmsQkQEaQcAAIAAoAjBrQQdNBEAgBCADEAYgACgCMCICQcEATw0CIABBNGpBACACEJEBGgsgAEHsAGogB0IDhjcCACAEIAMQBiAAQQA2AjAgASAAKAIINgAAIAEgAEEMaigCADYABCABIABBEGooAgA2AAggASAAQRRqKAIANgAMIAEgAEEYaigCADYAECABIABBHGooAgA2ABQgASAAQSBqKAIANgAYIAEgAEEkaigCADYAHCABIABBKGooAgA2ACAgASAAQSxqKAIANgAkDwsgAkHAAEGAmsAAEH4ACyACQcAAQZCawAAQfQALIAJBwABBoJrAABB8AAvwAgIGfwF+IwBBEGsiBCQAIABBDGohBSAAQcwAaiEDIAApAwAhCAJAAkAgACgCCCICQcAARgRAIAMgBRAKQQAhAiAAQQA2AggMAQsgAkE/Sw0BCyAAQQhqIgYgAmpBBGpBgAE6AAAgACAAKAIIIgdBAWoiAjYCCAJAIAJBwQBJBEAgAiAGakEEakEAQT8gB2sQkQEaQcAAIAAoAghrQQdNBEAgAyAFEAogACgCCCICQcEATw0CIABBDGpBACACEJEBGgsgAEHEAGogCEIDhjcCACADIAUQCiAAQQA2AgggBEEIaiICIABB3ABqNgIEIAIgAzYCACAEKAIMIAQoAggiAGtBAnYiA0EEIANBBEkbIgIEQEEAIQMDQCABIAAoAgA2AAAgAEEEaiEAIAFBBGohASADQQFqIgMgAkkNAAsLIARBEGokAA8LIAJBwABBgJrAABB+AAsgAkHAAEGQmsAAEH0ACyACQcAAQaCawAAQfAAL1AIBAX8gABBUIAEgACgCTCICQRh0IAJBCHRBgID8B3FyIAJBCHZBgP4DcSACQRh2cnI2AAAgASAAQdAAaigCACICQRh0IAJBCHRBgID8B3FyIAJBCHZBgP4DcSACQRh2cnI2AAQgASAAQdQAaigCACICQRh0IAJBCHRBgID8B3FyIAJBCHZBgP4DcSACQRh2cnI2AAggASAAQdgAaigCACICQRh0IAJBCHRBgID8B3FyIAJBCHZBgP4DcSACQRh2cnI2AAwgASAAQdwAaigCACICQRh0IAJBCHRBgID8B3FyIAJBCHZBgP4DcSACQRh2cnI2ABAgASAAQeAAaigCACICQRh0IAJBCHRBgID8B3FyIAJBCHZBgP4DcSACQRh2cnI2ABQgASAAQeQAaigCACIAQRh0IABBCHRBgID8B3FyIABBCHZBgP4DcSAAQRh2cnI2ABgL7AICBX8BfiMAQeAAayICJAAgASkDACEHIAJBIGogAUEMahBlIAJBCGoiAyABQdQAaikCADcDACACQRBqIgQgAUHcAGopAgA3AwAgAkEYaiIFIAFB5ABqKQIANwMAIAIgASkCTDcDACABKAIIIQZB8ABBCBChASIBRQRAQfAAQQhBtKXAACgCACIAQQIgABsRAAAACyABIAY2AgggASAHNwMAIAEgAikDIDcCDCABQRRqIAJBKGopAwA3AgAgAUEcaiACQTBqKQMANwIAIAFBJGogAkE4aikDADcCACABQSxqIAJBQGspAwA3AgAgAUE0aiACQcgAaikDADcCACABQTxqIAJB0ABqKQMANwIAIAFBxABqIAJB2ABqKQMANwIAIAFB5ABqIAUpAwA3AgAgAUHcAGogBCkDADcCACABQdQAaiADKQMANwIAIAEgAikDADcCTCAAQeCQwAA2AgQgACABNgIAIAJB4ABqJAAL7AICBX8BfiMAQeAAayICJAAgASkDACEHIAJBIGogAUEMahBlIAJBCGoiAyABQdQAaikCADcDACACQRBqIgQgAUHcAGopAgA3AwAgAkEYaiIFIAFB5ABqKQIANwMAIAIgASkCTDcDACABKAIIIQZB8ABBCBChASIBRQRAQfAAQQhBtKXAACgCACIAQQIgABsRAAAACyABIAY2AgggASAHNwMAIAEgAikDIDcCDCABQRRqIAJBKGopAwA3AgAgAUEcaiACQTBqKQMANwIAIAFBJGogAkE4aikDADcCACABQSxqIAJBQGspAwA3AgAgAUE0aiACQcgAaikDADcCACABQTxqIAJB0ABqKQMANwIAIAFBxABqIAJB2ABqKQMANwIAIAFB5ABqIAUpAwA3AgAgAUHcAGogBCkDADcCACABQdQAaiADKQMANwIAIAEgAikDADcCTCAAQYSRwAA2AgQgACABNgIAIAJB4ABqJAALyAICBH8BfiMAQeAAayICJAAgAkHQAGoiAyABQRBqKQMANwMAIAJB2ABqIgQgAUEYaigCADYCACACIAEpAwg3A0ggASkDACEGIAJBCGogAUEgahBlIAEoAhwhBUHgAEEIEKEBIgFFBEBB4ABBCEG0pcAAKAIAIgBBAiAAGxEAAAALIAEgBjcDACABIAIpA0g3AwggASAFNgIcIAEgAikDCDcDICABQRBqIAMpAwA3AwAgAUEYaiAEKAIANgIAIAFBKGogAkEQaikDADcDACABQTBqIAJBGGopAwA3AwAgAUE4aiACQSBqKQMANwMAIAFBQGsgAkEoaikDADcDACABQcgAaiACQTBqKQMANwMAIAFB0ABqIAJBOGopAwA3AwAgAUHYAGogAkFAaykDADcDACAAQYSNwAA2AgQgACABNgIAIAJB4ABqJAALyAICBH8BfiMAQeAAayICJAAgAkHQAGoiAyABQRBqKQMANwMAIAJB2ABqIgQgAUEYaigCADYCACACIAEpAwg3A0ggASkDACEGIAJBCGogAUEgahBlIAEoAhwhBUHgAEEIEKEBIgFFBEBB4ABBCEG0pcAAKAIAIgBBAiAAGxEAAAALIAEgBjcDACABIAIpA0g3AwggASAFNgIcIAEgAikDCDcDICABQRBqIAMpAwA3AwAgAUEYaiAEKAIANgIAIAFBKGogAkEQaikDADcDACABQTBqIAJBGGopAwA3AwAgAUE4aiACQSBqKQMANwMAIAFBQGsgAkEoaikDADcDACABQcgAaiACQTBqKQMANwMAIAFB0ABqIAJBOGopAwA3AwAgAUHYAGogAkFAaykDADcDACAAQbCNwAA2AgQgACABNgIAIAJB4ABqJAAL3QICBX8BfiAAQQxqIQIgAEHMAGohAyAAKQMAIQYCQAJAIAAoAggiAUHAAEYEQCADIAJBARAEQQAhASAAQQA2AggMAQsgAUE/Sw0BCyAAQQhqIgQgAWpBBGpBgAE6AAAgACAAKAIIIgVBAWoiATYCCAJAIAFBwQBJBEAgASAEakEEakEAQT8gBWsQkQEaQcAAIAAoAghrQQdNBEAgAyACQQEQBCAAKAIIIgFBwQBPDQIgAEEMakEAIAEQkQEaCyAAQcQAaiAGQiiGQoCAgICAgMD/AIMgBkI4hoQgBkIYhkKAgICAgOA/gyAGQgiGQoCAgIDwH4OEhCAGQgiIQoCAgPgPgyAGQhiIQoCA/AeDhCAGQiiIQoD+A4MgBkI4iISEhDcCACADIAJBARAEIABBADYCCA8LIAFBwABBgJrAABB+AAsgAUHAAEGQmsAAEH0ACyABQcAAQaCawAAQfAALvgICBX8BfiMAQTBrIgQkAEEnIQICQCAAQpDOAFQEQCAAIQcMAQsDQCAEQQlqIAJqIgNBfGogACAAQpDOAIAiB0LwsX9+fKciBUH//wNxQeQAbiIGQQF0QdqIwABqLwAAOwAAIANBfmogBkGcf2wgBWpB//8DcUEBdEHaiMAAai8AADsAACACQXxqIQIgAEL/wdcvViAHIQANAAsLIAenIgNB4wBKBEAgAkF+aiICIARBCWpqIAenIgVB//8DcUHkAG4iA0Gcf2wgBWpB//8DcUEBdEHaiMAAai8AADsAAAsCQCADQQpOBEAgAkF+aiICIARBCWpqIANBAXRB2ojAAGovAAA7AAAMAQsgAkF/aiICIARBCWpqIANBMGo6AAALIAFByKDAAEEAIARBCWogAmpBJyACaxAYIARBMGokAAu/AgEDfyMAQRBrIgIkAAJAIAAoAgAiAAJ/AkAgAUGAAU8EQCACQQA2AgwgAUGAEEkNASABQYCABEkEQCACIAFBP3FBgAFyOgAOIAIgAUEMdkHgAXI6AAwgAiABQQZ2QT9xQYABcjoADUEDDAMLIAIgAUE/cUGAAXI6AA8gAiABQRJ2QfABcjoADCACIAFBBnZBP3FBgAFyOgAOIAIgAUEMdkE/cUGAAXI6AA1BBAwCCyAAKAIIIgMgAEEEaigCAEYEfyAAQQEQaiAAKAIIBSADCyAAKAIAaiABOgAAIAAgACgCCEEBajYCCAwCCyACIAFBP3FBgAFyOgANIAIgAUEGdkHAAXI6AAxBAgsiARBqIABBCGoiAygCACIEIAAoAgBqIAJBDGogARCLARogAyABIARqNgIACyACQRBqJABBAAvLAgEIfyMAQYABayIBQShqIgJCADcDACABQSBqIgNCADcDACABQRhqIgRCADcDACABQRBqIgVCADcDACABQQhqIgZCADcDACABQgA3AwAgAUHaAGpCADcBACABQeIAakEAOwEAIAFBEDYCUCABQQA7AVQgAUEANgFWIAFB+ABqIAFB4ABqKAIANgIAIAFB8ABqIAFB2ABqKQMANwMAIAFByABqIgcgAUH0AGopAgA3AwAgASABKQNQNwNoIAEgASkCbDcDQCABQThqIgggBykDADcDACABIAEpA0A3AzAgAEHMAGogCCkDADcAACAAQcQAaiABKQMwNwAAIABBPGogAikDADcAACAAQTRqIAMpAwA3AAAgAEEsaiAEKQMANwAAIABBJGogBSkDADcAACAAQRxqIAYpAwA3AAAgACABKQMANwAUIABBADYCAAuxAgEDfyMAQYABayIEJAAgACgCACEAAkACQAJ/AkAgASgCACIDQRBxRQRAIAAoAgAhAiADQSBxDQEgAq0gARBVDAILIAAoAgAhAkEAIQADQCAAIARqQf8AaiACQQ9xIgNBMHIgA0HXAGogA0EKSRs6AAAgAEF/aiEAIAJBBHYiAg0ACyAAQYABaiICQYEBTw0CIAFB2IvAAEECIAAgBGpBgAFqQQAgAGsQGAwBC0EAIQADQCAAIARqQf8AaiACQQ9xIgNBMHIgA0E3aiADQQpJGzoAACAAQX9qIQAgAkEEdiICDQALIABBgAFqIgJBgQFPDQIgAUHYi8AAQQIgACAEakGAAWpBACAAaxAYCyAEQYABaiQADwsgAkGAAUHIi8AAEH4ACyACQYABQciLwAAQfgALrAICA38CfiAAIAApAwAiBiACrUIDhnwiBzcDACAAQQhqIgMgAykDACAHIAZUrXw3AwACQAJAQYABIAAoAlAiA2siBCACTQRAIABBEGoiBSADBEAgA0GBAU8NAiADIABB1ABqIgNqIAEgBBCLARogAEEANgJQIAUgA0EBEAwgAiAEayECIAEgBGohAQsgASACQQd2EAwgAkH/AHEiA0GBAU8NAiAAQdQAaiABIAJBgH9xaiADEIsBGiAAIAM2AlAPCwJAIAIgA2oiBCADTwRAIARBgAFLDQEgACADakHUAGogASACEIsBGiAAIAAoAlAgAmo2AlAPCyADIARB0JnAABB+AAsgBEGAAUHQmcAAEH0ACyADQYABQeCZwAAQfgALIANBgAFB8JnAABB9AAu8AgIFfwF+IABBIGohAyAAQQhqIQQgACkDACEHAkACQCAAKAIcIgJBwABGBEAgBCADEAdBACECIABBADYCHAwBCyACQT9LDQELIABBHGoiBSACakEEakGAAToAACAAIAAoAhwiBkEBaiICNgIcAkAgAkHBAEkEQCACIAVqQQRqQQBBPyAGaxCRARpBwAAgACgCHGtBB00EQCAEIAMQByAAKAIcIgJBwQBPDQIgAEEgakEAIAIQkQEaCyAAQdgAaiAHQgOGNwIAIAQgAxAHIABBADYCHCABIAAoAgg2AAAgASAAQQxqKAIANgAEIAEgAEEQaigCADYACCABIABBFGooAgA2AAwgASAAQRhqKAIANgAQDwsgAkHAAEGAmsAAEH4ACyACQcAAQZCawAAQfQALIAJBwABBoJrAABB8AAu1AgEDfyMAQRBrIgQkACAAKALIASICQccATQRAIAAgAmpBzAFqQQY6AAAgAkEBaiIDQcgARwRAIAAgA2pBzAFqQQBBxwAgAmsQkQEaC0EAIQIgAEEANgLIASAAQZMCaiIDIAMtAABBgAFyOgAAA0AgACACaiIDIAMtAAAgA0HMAWotAABzOgAAIAJBAWoiAkHIAEcNAAsgABAOIAEgACkAADcAACABQThqIABBOGopAAA3AAAgAUEwaiAAQTBqKQAANwAAIAFBKGogAEEoaikAADcAACABQSBqIABBIGopAAA3AAAgAUEYaiAAQRhqKQAANwAAIAFBEGogAEEQaikAADcAACABQQhqIABBCGopAAA3AAAgBEEQaiQADwtBsJrAAEEXIARBCGpByJrAAEGknsAAEHkAC7UCAQN/IwBBEGsiBCQAIAAoAsgBIgJBxwBNBEAgACACakHMAWpBAToAACACQQFqIgNByABHBEAgACADakHMAWpBAEHHACACaxCRARoLQQAhAiAAQQA2AsgBIABBkwJqIgMgAy0AAEGAAXI6AAADQCAAIAJqIgMgAy0AACADQcwBai0AAHM6AAAgAkEBaiICQcgARw0ACyAAEA4gASAAKQAANwAAIAFBOGogAEE4aikAADcAACABQTBqIABBMGopAAA3AAAgAUEoaiAAQShqKQAANwAAIAFBIGogAEEgaikAADcAACABQRhqIABBGGopAAA3AAAgAUEQaiAAQRBqKQAANwAAIAFBCGogAEEIaikAADcAACAEQRBqJAAPC0GwmsAAQRcgBEEIakHImsAAQeSdwAAQeQALswICBX8BfiAAQQxqIQMgAEHMAGohBCAAKQMAIQcCQAJAIAAoAggiAkHAAEYEQCAEIAMQDUEAIQIgAEEANgIIDAELIAJBP0sNAQsgAEEIaiIFIAJqQQRqQYABOgAAIAAgACgCCCIGQQFqIgI2AggCQCACQcEASQRAIAIgBWpBBGpBAEE/IAZrEJEBGkHAACAAKAIIa0EHTQRAIAQgAxANIAAoAggiAkHBAE8NAiAAQQxqQQAgAhCRARoLIABBxABqIAdCA4Y3AgAgBCADEA0gAEEANgIIIAEgACgCTDYAACABIABB0ABqKAIANgAEIAEgAEHUAGooAgA2AAggASAAQdgAaigCADYADA8LIAJBwABBgJrAABB+AAsgAkHAAEGQmsAAEH0ACyACQcAAQaCawAAQfAALhgIBBH8CQCAAQQRqKAIAIgYgAEEIaigCACIFayACTwRAIAAoAgAhBAwBCwJAAn8gAiAFaiIDIAVPBEBBACAGQQF0IgUgAyAFIANLGyIDQQggA0EISxsiA0EASA0BGgJAIAAoAgBBACAGGyIERQRAIANBARChASIEDQQMAQsgAyAGRg0DIAZFBEAgA0EBEKEBIgRFDQEMBAsgBCAGQQEgAxCaASIEDQMLQQEMAQtBAAsiBARAIAMgBEG0pcAAKAIAIgBBAiAAGxEAAAALEJsBAAsgACAENgIAIABBBGogAzYCACAAQQhqKAIAIQULIAQgBWogASACEIsBGiAAQQhqIAIgBWo2AgALjAIBA38gACAAKQMAIAKtQgOGfDcDAAJAAkBBwAAgACgCCCIDayIEIAJNBEAgAEHMAGoiBSADBEAgA0HBAE8NAiADIABBDGoiA2ogASAEEIsBGiAAQQA2AgggBSADQQEQBCACIARrIQIgASAEaiEBCyABIAJBBnYQBCACQT9xIgNBwQBPDQIgAEEMaiABIAJBQHFqIAMQiwEaIAAgAzYCCA8LAkAgAiADaiIEIANPBEAgBEHAAEsNASAAIANqQQxqIAEgAhCLARogACAAKAIIIAJqNgIIDwsgAyAEQdCZwAAQfgALIARBwABB0JnAABB9AAsgA0HAAEHgmcAAEH4ACyADQcAAQfCZwAAQfQALqAICA38BfiMAQdAAayICJAAgASkDACEFIAJBEGogAUEMahBlIAJBCGoiAyABQdQAaikCADcDACACIAEpAkw3AwAgASgCCCEEQeAAQQgQoQEiAUUEQEHgAEEIQbSlwAAoAgAiAEECIAAbEQAAAAsgASAENgIIIAEgBTcDACABIAIpAxA3AgwgAUEUaiACQRhqKQMANwIAIAFBHGogAkEgaikDADcCACABQSRqIAJBKGopAwA3AgAgAUEsaiACQTBqKQMANwIAIAFBNGogAkE4aikDADcCACABQTxqIAJBQGspAwA3AgAgAUHEAGogAkHIAGopAwA3AgAgAUHUAGogAykDADcCACABIAIpAwA3AkwgAEG8jMAANgIEIAAgATYCACACQdAAaiQAC4gCAQN/IAAgACkDACACrXw3AwACQAJAQcAAIAAoAhwiA2siBCACTQRAIABBCGoiBSADBEAgA0HBAE8NAiADIABBIGoiA2ogASAEEIsBGiAAQQA2AhwgBSADQQEQCCACIARrIQIgASAEaiEBCyABIAJBBnYQCCACQT9xIgNBwQBPDQIgAEEgaiABIAJBQHFqIAMQiwEaIAAgAzYCHA8LAkAgAiADaiIEIANPBEAgBEHAAEsNASAAIANqQSBqIAEgAhCLARogACAAKAIcIAJqNgIcDwsgAyAEQdCZwAAQfgALIARBwABB0JnAABB9AAsgA0HAAEHgmcAAEH4ACyADQcAAQfCZwAAQfQALqAICA38BfiMAQdAAayICJAAgASkDACEFIAJBEGogAUEMahBlIAJBCGoiAyABQdQAaikCADcDACACIAEpAkw3AwAgASgCCCEEQeAAQQgQoQEiAUUEQEHgAEEIQbSlwAAoAgAiAEECIAAbEQAAAAsgASAENgIIIAEgBTcDACABIAIpAxA3AgwgAUEUaiACQRhqKQMANwIAIAFBHGogAkEgaikDADcCACABQSRqIAJBKGopAwA3AgAgAUEsaiACQTBqKQMANwIAIAFBNGogAkE4aikDADcCACABQTxqIAJBQGspAwA3AgAgAUHEAGogAkHIAGopAwA3AgAgAUHUAGogAykDADcCACABIAIpAwA3AkwgAEGokcAANgIEIAAgATYCACACQdAAaiQAC5UCAQN/IwBBEGsiBCQAIAAoAsgBIgJB5wBNBEAgACACakHMAWpBBjoAACACQQFqIgNB6ABHBEAgACADakHMAWpBAEHnACACaxCRARoLQQAhAiAAQQA2AsgBIABBswJqIgMgAy0AAEGAAXI6AAADQCAAIAJqIgMgAy0AACADQcwBai0AAHM6AAAgAkEBaiICQegARw0ACyAAEA4gASAAKQAANwAAIAFBKGogAEEoaikAADcAACABQSBqIABBIGopAAA3AAAgAUEYaiAAQRhqKQAANwAAIAFBEGogAEEQaikAADcAACABQQhqIABBCGopAAA3AAAgBEEQaiQADwtBsJrAAEEXIARBCGpByJrAAEGUnsAAEHkAC5UCAQN/IwBBEGsiBCQAIAAoAsgBIgJB5wBNBEAgACACakHMAWpBAToAACACQQFqIgNB6ABHBEAgACADakHMAWpBAEHnACACaxCRARoLQQAhAiAAQQA2AsgBIABBswJqIgMgAy0AAEGAAXI6AAADQCAAIAJqIgMgAy0AACADQcwBai0AAHM6AAAgAkEBaiICQegARw0ACyAAEA4gASAAKQAANwAAIAFBKGogAEEoaikAADcAACABQSBqIABBIGopAAA3AAAgAUEYaiAAQRhqKQAANwAAIAFBEGogAEEQaikAADcAACABQQhqIABBCGopAAA3AAAgBEEQaiQADwtBsJrAAEEXIARBCGpByJrAAEHUncAAEHkAC/MBAQR/IwBBkAFrIgIkACACQQA2AgAgAkEEciEFA0AgAyAFaiABIANqLQAAOgAAIAIgAigCAEEBaiIENgIAIANBAWoiA0HAAEcNAAsgBEE/TQRAIARBwAAQfwALIAJByABqIAJBxAAQiwEaIABBOGogAkGEAWopAgA3AAAgAEEwaiACQfwAaikCADcAACAAQShqIAJB9ABqKQIANwAAIABBIGogAkHsAGopAgA3AAAgAEEYaiACQeQAaikCADcAACAAQRBqIAJB3ABqKQIANwAAIABBCGogAkHUAGopAgA3AAAgACACKQJMNwAAIAJBkAFqJAAL9QEBA38jAEEQayIEJAAgACgCyAEiAkGHAU0EQCAAIAJqQcwBakEBOgAAIAJBAWoiA0GIAUcEQCAAIANqQcwBakEAQYcBIAJrEJEBGgtBACECIABBADYCyAEgAEHTAmoiAyADLQAAQYABcjoAAANAIAAgAmoiAyADLQAAIANBzAFqLQAAczoAACACQQFqIgJBiAFHDQALIAAQDiABIAApAAA3AAAgAUEYaiAAQRhqKQAANwAAIAFBEGogAEEQaikAADcAACABQQhqIABBCGopAAA3AAAgBEEQaiQADwtBsJrAAEEXIARBCGpByJrAAEHEncAAEHkAC/UBAQN/IwBBEGsiBCQAIAAoAsgBIgJBhwFNBEAgACACakHMAWpBBjoAACACQQFqIgNBiAFHBEAgACADakHMAWpBAEGHASACaxCRARoLQQAhAiAAQQA2AsgBIABB0wJqIgMgAy0AAEGAAXI6AAADQCAAIAJqIgMgAy0AACADQcwBai0AAHM6AAAgAkEBaiICQYgBRw0ACyAAEA4gASAAKQAANwAAIAFBGGogAEEYaikAADcAACABQRBqIABBEGopAAA3AAAgAUEIaiAAQQhqKQAANwAAIARBEGokAA8LQbCawABBFyAEQQhqQciawABBhJ7AABB5AAv1AQEDfyMAQRBrIgQkACAAKALIASICQY8BTQRAIAAgAmpBzAFqQQE6AAAgAkEBaiIDQZABRwRAIAAgA2pBzAFqQQBBjwEgAmsQkQEaC0EAIQIgAEEANgLIASAAQdsCaiIDIAMtAABBgAFyOgAAA0AgACACaiIDIAMtAAAgA0HMAWotAABzOgAAIAJBAWoiAkGQAUcNAAsgABAOIAEgACkAADcAACABQRhqIABBGGooAAA2AAAgAUEQaiAAQRBqKQAANwAAIAFBCGogAEEIaikAADcAACAEQRBqJAAPC0GwmsAAQRcgBEEIakHImsAAQdiawAAQeQAL9QEBA38jAEEQayIEJAAgACgCyAEiAkGPAU0EQCAAIAJqQcwBakEGOgAAIAJBAWoiA0GQAUcEQCAAIANqQcwBakEAQY8BIAJrEJEBGgtBACECIABBADYCyAEgAEHbAmoiAyADLQAAQYABcjoAAANAIAAgAmoiAyADLQAAIANBzAFqLQAAczoAACACQQFqIgJBkAFHDQALIAAQDiABIAApAAA3AAAgAUEYaiAAQRhqKAAANgAAIAFBEGogAEEQaikAADcAACABQQhqIABBCGopAAA3AAAgBEEQaiQADwtBsJrAAEEXIARBCGpByJrAAEH0ncAAEHkAC8MBAQJ/AkACQCAAQQRqKAIAIgMgACgCCCICayABSQRAIAEgAmoiASACSQ0BIANBAXQiAiABIAIgAUsbIgFBCCABQQhLGyICQQBIDQECQCAAKAIAQQAgAxsiAUUEQCACQQEQoQEhAQwBCyACIANGDQAgA0UEQCACQQEQoQEhAQwBCyABIANBASACEJoBIQELIAFFDQIgACABNgIAIABBBGogAjYCAAsPCxCbAQALIAJBAUG0pcAAKAIAIgBBAiAAGxEAAAALhQEBBH8jAEGgAWsiAiQAIAJBADYCACACQQRyIQUDQCADIAVqIAEgA2otAAA6AAAgAiACKAIAQQFqIgQ2AgAgA0EBaiIDQcgARw0A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JAAgAkGIAWogAUHIARCLARogAiABQcwBahBuIAEoAsgBIQNB2AJBCBChASIBRQRAQdgCQQhBtKXAACgCACIAQQIgABsRAAAACyABIAJBiAFqQcgBEIsBIgEgAzYCyAEgAUHMAWogAkGIARCLARogAEGsj8AANgIEIAAgATYCACACQdACaiQAC34BAX8jAEFAaiIFJAAgBSABNgIMIAUgADYCCCAFIAM2AhQgBSACNgIQIAVBLGpBAjYCACAFQTxqQQQ2AgAgBUICNwIcIAVB8IvAADYCGCAFQQE2AjQgBSAFQTBqNgIoIAUgBUEQajYCOCAFIAVBCGo2AjAgBUEYaiAEEJABAAuVAQAgAEIANwMIIABCADcDACAAQQA2AlAgAEGQmcAAKQMANwMQIABBGGpBmJnAACkDADcDACAAQSBqQaCZwAApAwA3AwAgAEEoakGomcAAKQMANwMAIABBMGpBsJnAACkDADcDACAAQThqQbiZwAApAwA3AwAgAEFAa0HAmcAAKQMANwMAIABByABqQciZwAApAwA3AwALlQEAIABCADcDCCAAQgA3AwAgAEEANgJQIABB0JjAACkDADcDECAAQRhqQdiYwAApAwA3AwAgAEEgakHgmMAAKQMANwMAIABBKGpB6JjAACkDADcDACAAQTBqQfCYwAApAwA3AwAgAEE4akH4mMAAKQMANwMAIABBQGtBgJnAACkDADcDACAAQcgAakGImcAAKQMANwMAC20BAX8jAEEwayIDJAAgAyABNgIEIAMgADYCACADQRxqQQI2AgAgA0EsakEFNgIAIANCAjcCDCADQYiIwAA2AgggA0EFNgIkIAMgA0EgajYCGCADIAM2AiggAyADQQRqNgIgIANBCGogAhCQAQALbQEBfyMAQTBrIgMkACADIAE2AgQgAyAANgIAIANBHGpBAjYCACADQSxqQQU2AgAgA0ICNwIMIANBpIrAADYCCCADQQU2AiQgAyADQSBqNgIYIAMgA0EEajYCKCADIAM2AiAgA0EIaiACEJABAAttAQF/IwBBMGsiAyQAIAMgATYCBCADIAA2AgAgA0EcakECNgIAIANBLGpBBTYCACADQgI3AgwgA0HcisAANgIIIANBBTYCJCADIANBIGo2AhggAyADQQRqNgIoIAMgAzYCICADQQhqIAIQkAEAC3ABAX8jAEEwayICJAAgAiABNgIEIAIgADYCACACQRxqQQI2AgAgAkEsakEFNgIAIAJCAjcCDCACQcyRwAA2AgggAkEFNgIkIAIgAkEgajYCGCACIAJBBGo2AiggAiACNgIgIAJBCGpB3JHAABCQAQALVAEBfyMAQSBrIgIkACACIAAoAgA2AgQgAkEYaiABQRBqKQIANwMAIAJBEGogAUEIaikCADcDACACIAEpAgA3AwggAkEEaiACQQhqEBYgAkEgaiQAC30BAn9BASEAQeChwABB4KHAACgCAEEBajYCAAJAAkBBqKXAACgCAEEBRwRAQailwABCgYCAgBA3AwAMAQtBrKXAAEGspcAAKAIAQQFqIgA2AgAgAEECSw0BC0GwpcAAKAIAIgFBf0wNAEGwpcAAIAE2AgAgAEEBSw0AAAsAC2ICAX8BfiMAQRBrIgIkAAJAIAEEQCABKAIADQEgAUF/NgIAIAJBCGogASgCBCABQQhqKAIAKAIQEQAAIAIpAwghAyABQQA2AgAgACADNwIAIAJBEGokAA8LEJ0BAAsQngEAC0MBA38CQCACRQ0AA0AgAC0AACIEIAEtAAAiBUYEQCAAQQFqIQAgAUEBaiEBIAJBf2oiAg0BDAILCyAEIAVrIQMLIAMLSwECfwJAIAAEQCAAKAIADQEgAEEANgIAIAAoAgQhASAAKAIIIQIgABAQIAEgAigCABEEACACKAIEBEAgARAQCw8LEJ0BAAsQngEAC0gAAkAgAARAIAAoAgANASAAQX82AgAgACgCBCABIAIgAEEIaigCACgCDBECACACBEAgARAQCyAAQQA2AgAPCxCdAQALEJ4BAAtKAAJ/IAFBgIDEAEcEQEEBIAAoAhggASAAQRxqKAIAKAIQEQEADQEaCyACRQRAQQAPCyAAKAIYIAIgAyAAQRxqKAIAKAIMEQMACwtdACAAQgA3AwAgAEEANgIwIABB0JfAACkDADcDCCAAQRBqQdiXwAApAwA3AwAgAEEYakHgl8AAKQMANwMAIABBIGpB6JfAACkDADcDACAAQShqQfCXwAApAwA3AwALSAEBfyMAQSBrIgMkACADQRRqQQA2AgAgA0HIoMAANgIQIANCATcCBCADIAE2AhwgAyAANgIYIAMgA0EYajYCACADIAIQkAEAC1AAIABBADYCCCAAQgA3AwAgAEGsmMAAKQIANwJMIABB1ABqQbSYwAApAgA3AgAgAEHcAGpBvJjAACkCADcCACAAQeQAakHEmMAAKQIANwIAC1AAIABBADYCCCAAQgA3AwAgAEGMmMAAKQIANwJMIABB1ABqQZSYwAApAgA3AgAgAEHcAGpBnJjAACkCADcCACAAQeQAakGkmMAAKQIANwIACzMBAX8gAgRAIAAhAwNAIAMgAS0AADoAACABQQFqIQEgA0EBaiEDIAJBf2oiAg0ACwsgAAs1AQJ/IAAoAgAiACACEGogAEEIaiIDKAIAIgQgACgCAGogASACEIsBGiADIAIgBGo2AgBBAAsrAAJAIABBfEsNACAARQRAQQQPCyAAIABBfUlBAnQQoQEiAEUNACAADwsACz0AIABCADcDACAAQQA2AhwgAEH4l8AAKQMANwMIIABBEGpBgJjAACkDADcDACAAQRhqQYiYwAAoAgA2AgALPQAgAEEANgIcIABCADcDACAAQRhqQYiYwAAoAgA2AgAgAEEQakGAmMAAKQMANwMAIABB+JfAACkDADcDCAtMAQF/IwBBEGsiAiQAIAIgATYCDCACIAA2AgggAkGYiMAANgIEIAJByKDAADYCACACKAIIRQRAQZ2gwABBK0HIoMAAEIgBAAsQgQEACykBAX8gAgRAIAAhAwNAIAMgAToAACADQQFqIQMgAkF/aiICDQALCyAACy4AIABBADYCCCAAQgA3AwAgAEHUAGpByJfAACkCADcCACAAQcCXwAApAgA3AkwLIAACQCABQXxLDQAgACABQQQgAhCaASIARQ0AIAAPCwALHAAgASgCGEH/h8AAQQggAUEcaigCACgCDBEDAAscACABKAIYQYKMwABBBSABQRxqKAIAKAIMEQMACxQAIAAoAgAgASAAKAIEKAIMEQEACxAAIAEgACgCACAAKAIEEBILEgAgAEEAQcgBEJEBQQA2AsgBCwsAIAEEQCAAEBALCwwAIAAgASACIAMQFwsSAEHEhsAAQRFB2IbAABCIAQALDgAgACgCABoDQAwACwALDQBB76DAAEEbEKABAAsOAEGKocAAQc8AEKABAAsLACAANQIAIAEQVQsJACAAIAEQAQALGQACfyABQQlPBEAgASAAEEYMAQsgABAJCwsNAEKtqduM/5imovgACwQAQRALBABBKAsEAEEUCwUAQcAACwQA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AAAvaG9tZS9sdWNhY2Fzb25hdG8vLmNhcmdvL3JlZ2lzdHJ5L3NyYy9naXRodWIuY29tLTFlY2M2Mjk5ZGI5ZWM4MjMvYmxvY2stYnVmZmVyLTAuOS4wL3NyYy9saWIucnMvaG9tZS9sdWNhY2Fzb25hdG8vLnJ1c3R1cC90b29sY2hhaW5zL3N0YWJsZS14ODZfNjQtdW5rbm93bi1saW51eC1nbnUvbGliL3J1c3RsaWIvc3JjL3J1c3Qvc3JjL2xpYmNvcmUvc2xpY2UvbW9kLnJzAGgNEABYAAAASAAAAAEAAABoDRAAWAAAAE8AAAABAAAAaA0QAFgAAABWAAAAAQAAAGgNEABYAAAAZgAAAAEAAABoDRAAWAAAAG0AAAABAAAAaA0QAFgAAAB0AAAAAQAAAGgNEABYAAAAewAAAAEAAACQAAAA5A8QAC0AAAAREBAADAAAAFAPEAABAAAAYAAAAIgAAABoAAAASAAAAHAPEAB0AAAAEAAAAAkAAAAvaG9tZS9sdWNhY2Fzb25hdG8vLnJ1c3R1cC90b29sY2hhaW5zL3N0YWJsZS14ODZfNjQtdW5rbm93bi1saW51eC1nbnUvbGliL3J1c3RsaWIvc3JjL3J1c3Qvc3JjL2xpYmNvcmUvbWFjcm9zL21vZC5yc2Fzc2VydGlvbiBmYWlsZWQ6IGAobGVmdCA9PSByaWdodClgCiAgbGVmdDogYGAsCiByaWdodDogYGNhbGxlZCBgT3B0aW9uOjp1bndyYXAoKWAgb24gYSBgTm9uZWAgdmFsdWVYEBAAFwAAALQBAAAeAAAAc3JjL2xpYnN0ZC9wYW5pY2tpbmcucnNudWxsIHBvaW50ZXIgcGFzc2VkIHRvIHJ1c3RyZWN1cnNpdmUgdXNlIG9mIGFuIG9iamVjdCBkZXRlY3RlZCB3aGljaCB3b3VsZCBsZWFkIHRvIHVuc2FmZSBhbGlhc2luZyBpbiBydXN0AHsJcHJvZHVjZXJzAghsYW5ndWFnZQEEUnVzdAAMcHJvY2Vzc2VkLWJ5AwVydXN0Yx0xLjQ2LjAgKDA0NDg4YWZlMyAyMDIwLTA4LTI0KQZ3YWxydXMGMC4xOC4wDHdhc20tYmluZGdlbhIwLjIuNjggKGEwNGUxODk3MSk="); -let wasm; - -let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }); - -cachedTextDecoder.decode(); - -let cachegetUint8Memory0 = null; -function getUint8Memory0() { - if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.memory.buffer) { - cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer); - } - return cachegetUint8Memory0; -} - -function getStringFromWasm0(ptr, len) { - return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len)); -} - -const heap = new Array(32).fill(undefined); - -heap.push(undefined, null, true, false); - -let heap_next = heap.length; - -function addHeapObject(obj) { - if (heap_next === heap.length) heap.push(heap.length + 1); - const idx = heap_next; - heap_next = heap[idx]; - - heap[idx] = obj; - return idx; -} - -function getObject(idx) { return heap[idx]; } - -function dropObject(idx) { - if (idx < 36) return; - heap[idx] = heap_next; - heap_next = idx; -} - -function takeObject(idx) { - const ret = getObject(idx); - dropObject(idx); - return ret; -} - -let WASM_VECTOR_LEN = 0; - -let cachedTextEncoder = new TextEncoder('utf-8'); - -const encodeString = (typeof cachedTextEncoder.encodeInto === 'function' - ? function (arg, view) { - return cachedTextEncoder.encodeInto(arg, view); -} - : function (arg, view) { - const buf = cachedTextEncoder.encode(arg); - view.set(buf); - return { - read: arg.length, - written: buf.length - }; -}); - -function passStringToWasm0(arg, malloc, realloc) { - - if (realloc === undefined) { - const buf = cachedTextEncoder.encode(arg); - const ptr = malloc(buf.length); - getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf); - WASM_VECTOR_LEN = buf.length; - return ptr; - } - - let len = arg.length; - let ptr = malloc(len); - - const mem = getUint8Memory0(); - - let offset = 0; - - for (; offset < len; offset++) { - const code = arg.charCodeAt(offset); - if (code > 0x7F) break; - mem[ptr + offset] = code; - } - - if (offset !== len) { - if (offset !== 0) { - arg = arg.slice(offset); - } - ptr = realloc(ptr, len, len = offset + arg.length * 3); - const view = getUint8Memory0().subarray(ptr + offset, ptr + len); - const ret = encodeString(arg, view); - - offset += ret.written; - } - - WASM_VECTOR_LEN = offset; - return ptr; -} -/** -* @param {string} algorithm -* @returns {DenoHash} -*/ -export function create_hash(algorithm) { - var ptr0 = passStringToWasm0(algorithm, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - var len0 = WASM_VECTOR_LEN; - var ret = wasm.create_hash(ptr0, len0); - return DenoHash.__wrap(ret); -} - -function _assertClass(instance, klass) { - if (!(instance instanceof klass)) { - throw new Error(`expected instance of ${klass.name}`); - } - return instance.ptr; -} - -function passArray8ToWasm0(arg, malloc) { - const ptr = malloc(arg.length * 1); - getUint8Memory0().set(arg, ptr / 1); - WASM_VECTOR_LEN = arg.length; - return ptr; -} -/** -* @param {DenoHash} hash -* @param {Uint8Array} data -*/ -export function update_hash(hash, data) { - _assertClass(hash, DenoHash); - var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc); - var len0 = WASM_VECTOR_LEN; - wasm.update_hash(hash.ptr, ptr0, len0); -} - -let cachegetInt32Memory0 = null; -function getInt32Memory0() { - if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) { - cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer); - } - return cachegetInt32Memory0; -} - -function getArrayU8FromWasm0(ptr, len) { - return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len); -} -/** -* @param {DenoHash} hash -* @returns {Uint8Array} -*/ -export function digest_hash(hash) { - try { - const retptr = wasm.__wbindgen_export_2.value - 16; - wasm.__wbindgen_export_2.value = retptr; - _assertClass(hash, DenoHash); - wasm.digest_hash(retptr, hash.ptr); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var v0 = getArrayU8FromWasm0(r0, r1).slice(); - wasm.__wbindgen_free(r0, r1 * 1); - return v0; - } finally { - wasm.__wbindgen_export_2.value += 16; - } -} - -/** -*/ -export class DenoHash { - - static __wrap(ptr) { - const obj = Object.create(DenoHash.prototype); - obj.ptr = ptr; - - return obj; - } - - free() { - const ptr = this.ptr; - this.ptr = 0; - - wasm.__wbg_denohash_free(ptr); - } -} - -async function load(module, imports) { - if (typeof Response === 'function' && module instanceof Response) { - - if (typeof WebAssembly.instantiateStreaming === 'function') { - try { - return await WebAssembly.instantiateStreaming(module, imports); - - } catch (e) { - if (module.headers.get('Content-Type') != 'application/wasm') { - console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e); - - } else { - throw e; - } - } - } - - const bytes = await module.arrayBuffer(); - return await WebAssembly.instantiate(bytes, imports); - - } else { - - const instance = await WebAssembly.instantiate(module, imports); - - if (instance instanceof WebAssembly.Instance) { - return { instance, module }; - - } else { - return instance; - } - } -} - -async function init(input) { - if (typeof input === 'undefined') { - input = import.meta.url.replace(/\.js$/, '_bg.wasm'); - } - const imports = {}; - imports.wbg = {}; - imports.wbg.__wbindgen_string_new = function(arg0, arg1) { - var ret = getStringFromWasm0(arg0, arg1); - return addHeapObject(ret); - }; - imports.wbg.__wbindgen_throw = function(arg0, arg1) { - throw new Error(getStringFromWasm0(arg0, arg1)); - }; - imports.wbg.__wbindgen_rethrow = function(arg0) { - throw takeObject(arg0); - }; - - if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) { - input = fetch(input); - } - - const { instance, module } = await load(await input, imports); - - wasm = instance.exports; - init.__wbindgen_wasm_module = module; - - return wasm; -} - -export default init; - diff --git a/std/hash/fnv.ts b/std/hash/fnv.ts deleted file mode 100644 index 8c0ba21c1..000000000 --- a/std/hash/fnv.ts +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -export { Fnv32, Fnv32a } from "./_fnv/fnv32.ts"; -export { Fnv64, Fnv64a } from "./_fnv/fnv64.ts"; diff --git a/std/hash/fnv_test.ts b/std/hash/fnv_test.ts deleted file mode 100644 index 923c63d9e..000000000 --- a/std/hash/fnv_test.ts +++ /dev/null @@ -1,111 +0,0 @@ -// Ported from Go: -// https://github.com/golang/go/tree/go1.13.10/src/hash/fnv/fnv_test.go -// Copyright 2011 The Go Authors. All rights reserved. BSD license. -// https://github.com/golang/go/blob/master/LICENSE -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -import { assertEquals } from "../testing/asserts.ts"; -import { Fnv32, Fnv32a, Fnv64, Fnv64a } from "./fnv.ts"; - -const golden32 = [ - ["", [0x81, 0x1c, 0x9d, 0xc5]], - ["a", [0x05, 0x0c, 0x5d, 0x7e]], - ["ab", [0x70, 0x77, 0x2d, 0x38]], - ["abc", [0x43, 0x9c, 0x2f, 0x4b]], - ["deno", [0x6e, 0xd5, 0xa7, 0xa9]], -]; - -const golden32a = [ - ["", [0x81, 0x1c, 0x9d, 0xc5]], - ["a", [0xe4, 0x0c, 0x29, 0x2c]], - ["ab", [0x4d, 0x25, 0x05, 0xca]], - ["abc", [0x1a, 0x47, 0xe9, 0x0b]], - ["deno", [0x8e, 0xf6, 0x47, 0x11]], -]; - -const golden64 = [ - ["", [0xcb, 0xf2, 0x9c, 0xe4, 0x84, 0x22, 0x23, 0x25]], - ["a", [0xaf, 0x63, 0xbd, 0x4c, 0x86, 0x01, 0xb7, 0xbe]], - ["ab", [0x08, 0x32, 0x67, 0x07, 0xb4, 0xeb, 0x37, 0xb8]], - ["abc", [0xd8, 0xdc, 0xca, 0x18, 0x6b, 0xaf, 0xad, 0xcb]], - ["deno", [0x14, 0xed, 0xb2, 0x7e, 0xec, 0xda, 0xad, 0xc9]], -]; - -const golden64a = [ - ["", [0xcb, 0xf2, 0x9c, 0xe4, 0x84, 0x22, 0x23, 0x25]], - ["a", [0xaf, 0x63, 0xdc, 0x4c, 0x86, 0x01, 0xec, 0x8c]], - ["ab", [0x08, 0x9c, 0x44, 0x07, 0xb5, 0x45, 0x98, 0x6a]], - ["abc", [0xe7, 0x1f, 0xa2, 0x19, 0x05, 0x41, 0x57, 0x4b]], - ["deno", [0xa5, 0xd9, 0xfb, 0x67, 0x42, 0x6e, 0x48, 0xb1]], -]; - -Deno.test("[hash/fnv] testFnv32", () => { - for (const [input, output] of golden32) { - const fnv = new Fnv32(); - fnv.write(new TextEncoder().encode(input as string)); - assertEquals(fnv.sum(), output); - } -}); - -Deno.test("[hash/fnv] testFnv32a", () => { - for (const [input, output] of golden32a) { - const fnv = new Fnv32a(); - fnv.write(new TextEncoder().encode(input as string)); - assertEquals(fnv.sum(), output); - } -}); - -Deno.test("[hash/fnv] testFnv64", () => { - for (const [input, output] of golden64) { - const fnv = new Fnv64(); - fnv.write(new TextEncoder().encode(input as string)); - assertEquals(fnv.sum(), output); - } -}); - -Deno.test("[hash/fnv] testFnv64a", () => { - for (const [input, output] of golden64a) { - const fnv = new Fnv64a(); - fnv.write(new TextEncoder().encode(input as string)); - assertEquals(fnv.sum(), output); - } -}); - -Deno.test("[hash/fnv] testFnv32WriteChain", () => { - const fnv = new Fnv32(); - fnv - .write(new TextEncoder().encode("d")) - .write(new TextEncoder().encode("e")) - .write(new TextEncoder().encode("n")) - .write(new TextEncoder().encode("o")); - assertEquals(fnv.sum(), [0x6e, 0xd5, 0xa7, 0xa9]); -}); - -Deno.test("[hash/fnv] testFnv32aWriteChain", () => { - const fnv = new Fnv32a(); - fnv - .write(new TextEncoder().encode("d")) - .write(new TextEncoder().encode("e")) - .write(new TextEncoder().encode("n")) - .write(new TextEncoder().encode("o")); - assertEquals(fnv.sum(), [0x8e, 0xf6, 0x47, 0x11]); -}); - -Deno.test("[hash/fnv] testFnv64WriteChain", () => { - const fnv = new Fnv64(); - fnv - .write(new TextEncoder().encode("d")) - .write(new TextEncoder().encode("e")) - .write(new TextEncoder().encode("n")) - .write(new TextEncoder().encode("o")); - assertEquals(fnv.sum(), [0x14, 0xed, 0xb2, 0x7e, 0xec, 0xda, 0xad, 0xc9]); -}); - -Deno.test("[hash/fnv] testFnv64aWriteChain", () => { - const fnv = new Fnv64a(); - fnv - .write(new TextEncoder().encode("d")) - .write(new TextEncoder().encode("e")) - .write(new TextEncoder().encode("n")) - .write(new TextEncoder().encode("o")); - assertEquals(fnv.sum(), [0xa5, 0xd9, 0xfb, 0x67, 0x42, 0x6e, 0x48, 0xb1]); -}); diff --git a/std/hash/hasher.ts b/std/hash/hasher.ts deleted file mode 100644 index e04cb56ef..000000000 --- a/std/hash/hasher.ts +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -export type Message = string | ArrayBuffer; -export type OutputFormat = "hex" | "base64"; - -export interface Hasher { - update(data: Message): this; - digest(): ArrayBuffer; - toString(format?: OutputFormat): string; -} diff --git a/std/hash/md5.ts b/std/hash/md5.ts deleted file mode 100644 index 36984d3ab..000000000 --- a/std/hash/md5.ts +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -import * as hex from "../encoding/hex.ts"; - -const TYPE_ERROR_MSG = "md5: `data` is invalid type"; -const BLOCK_SIZE = 64; - -export type Message = string | ArrayBuffer; - -/** Md5 hash */ -export class Md5 { - #a: number; - #b: number; - #c: number; - #d: number; - #block: Uint8Array; - #pos: number; - #n0: number; - #n1: number; - - constructor() { - this.#a = 0x67452301; - this.#b = 0xefcdab89; - this.#c = 0x98badcfe; - this.#d = 0x10325476; - this.#block = new Uint8Array(BLOCK_SIZE); - this.#pos = 0; - this.#n0 = 0; - this.#n1 = 0; - } - - private addLength(len: number): void { - let n0 = this.#n0; - n0 += len; - if (n0 > 0xffffffff) this.#n1 += 1; - this.#n0 = n0 >>> 0; - } - - private hash(block: Uint8Array): void { - let a = this.#a; - let b = this.#b; - let c = this.#c; - let d = this.#d; - - const blk = (i: number): number => - block[i] | - (block[i + 1] << 8) | - (block[i + 2] << 16) | - (block[i + 3] << 24); - - const rol32 = (x: number, n: number): number => (x << n) | (x >>> (32 - n)); - - const x0 = blk(0); - const x1 = blk(4); - const x2 = blk(8); - const x3 = blk(12); - const x4 = blk(16); - const x5 = blk(20); - const x6 = blk(24); - const x7 = blk(28); - const x8 = blk(32); - const x9 = blk(36); - const xa = blk(40); - const xb = blk(44); - const xc = blk(48); - const xd = blk(52); - const xe = blk(56); - const xf = blk(60); - - // round 1 - a = b + rol32((((c ^ d) & b) ^ d) + a + x0 + 0xd76aa478, 7); - d = a + rol32((((b ^ c) & a) ^ c) + d + x1 + 0xe8c7b756, 12); - c = d + rol32((((a ^ b) & d) ^ b) + c + x2 + 0x242070db, 17); - b = c + rol32((((d ^ a) & c) ^ a) + b + x3 + 0xc1bdceee, 22); - a = b + rol32((((c ^ d) & b) ^ d) + a + x4 + 0xf57c0faf, 7); - d = a + rol32((((b ^ c) & a) ^ c) + d + x5 + 0x4787c62a, 12); - c = d + rol32((((a ^ b) & d) ^ b) + c + x6 + 0xa8304613, 17); - b = c + rol32((((d ^ a) & c) ^ a) + b + x7 + 0xfd469501, 22); - a = b + rol32((((c ^ d) & b) ^ d) + a + x8 + 0x698098d8, 7); - d = a + rol32((((b ^ c) & a) ^ c) + d + x9 + 0x8b44f7af, 12); - c = d + rol32((((a ^ b) & d) ^ b) + c + xa + 0xffff5bb1, 17); - b = c + rol32((((d ^ a) & c) ^ a) + b + xb + 0x895cd7be, 22); - a = b + rol32((((c ^ d) & b) ^ d) + a + xc + 0x6b901122, 7); - d = a + rol32((((b ^ c) & a) ^ c) + d + xd + 0xfd987193, 12); - c = d + rol32((((a ^ b) & d) ^ b) + c + xe + 0xa679438e, 17); - b = c + rol32((((d ^ a) & c) ^ a) + b + xf + 0x49b40821, 22); - - // round 2 - a = b + rol32((((b ^ c) & d) ^ c) + a + x1 + 0xf61e2562, 5); - d = a + rol32((((a ^ b) & c) ^ b) + d + x6 + 0xc040b340, 9); - c = d + rol32((((d ^ a) & b) ^ a) + c + xb + 0x265e5a51, 14); - b = c + rol32((((c ^ d) & a) ^ d) + b + x0 + 0xe9b6c7aa, 20); - a = b + rol32((((b ^ c) & d) ^ c) + a + x5 + 0xd62f105d, 5); - d = a + rol32((((a ^ b) & c) ^ b) + d + xa + 0x02441453, 9); - c = d + rol32((((d ^ a) & b) ^ a) + c + xf + 0xd8a1e681, 14); - b = c + rol32((((c ^ d) & a) ^ d) + b + x4 + 0xe7d3fbc8, 20); - a = b + rol32((((b ^ c) & d) ^ c) + a + x9 + 0x21e1cde6, 5); - d = a + rol32((((a ^ b) & c) ^ b) + d + xe + 0xc33707d6, 9); - c = d + rol32((((d ^ a) & b) ^ a) + c + x3 + 0xf4d50d87, 14); - b = c + rol32((((c ^ d) & a) ^ d) + b + x8 + 0x455a14ed, 20); - a = b + rol32((((b ^ c) & d) ^ c) + a + xd + 0xa9e3e905, 5); - d = a + rol32((((a ^ b) & c) ^ b) + d + x2 + 0xfcefa3f8, 9); - c = d + rol32((((d ^ a) & b) ^ a) + c + x7 + 0x676f02d9, 14); - b = c + rol32((((c ^ d) & a) ^ d) + b + xc + 0x8d2a4c8a, 20); - - // round 3 - a = b + rol32((b ^ c ^ d) + a + x5 + 0xfffa3942, 4); - d = a + rol32((a ^ b ^ c) + d + x8 + 0x8771f681, 11); - c = d + rol32((d ^ a ^ b) + c + xb + 0x6d9d6122, 16); - b = c + rol32((c ^ d ^ a) + b + xe + 0xfde5380c, 23); - a = b + rol32((b ^ c ^ d) + a + x1 + 0xa4beea44, 4); - d = a + rol32((a ^ b ^ c) + d + x4 + 0x4bdecfa9, 11); - c = d + rol32((d ^ a ^ b) + c + x7 + 0xf6bb4b60, 16); - b = c + rol32((c ^ d ^ a) + b + xa + 0xbebfbc70, 23); - a = b + rol32((b ^ c ^ d) + a + xd + 0x289b7ec6, 4); - d = a + rol32((a ^ b ^ c) + d + x0 + 0xeaa127fa, 11); - c = d + rol32((d ^ a ^ b) + c + x3 + 0xd4ef3085, 16); - b = c + rol32((c ^ d ^ a) + b + x6 + 0x04881d05, 23); - a = b + rol32((b ^ c ^ d) + a + x9 + 0xd9d4d039, 4); - d = a + rol32((a ^ b ^ c) + d + xc + 0xe6db99e5, 11); - c = d + rol32((d ^ a ^ b) + c + xf + 0x1fa27cf8, 16); - b = c + rol32((c ^ d ^ a) + b + x2 + 0xc4ac5665, 23); - - // round 4 - a = b + rol32((c ^ (b | ~d)) + a + x0 + 0xf4292244, 6); - d = a + rol32((b ^ (a | ~c)) + d + x7 + 0x432aff97, 10); - c = d + rol32((a ^ (d | ~b)) + c + xe + 0xab9423a7, 15); - b = c + rol32((d ^ (c | ~a)) + b + x5 + 0xfc93a039, 21); - a = b + rol32((c ^ (b | ~d)) + a + xc + 0x655b59c3, 6); - d = a + rol32((b ^ (a | ~c)) + d + x3 + 0x8f0ccc92, 10); - c = d + rol32((a ^ (d | ~b)) + c + xa + 0xffeff47d, 15); - b = c + rol32((d ^ (c | ~a)) + b + x1 + 0x85845dd1, 21); - a = b + rol32((c ^ (b | ~d)) + a + x8 + 0x6fa87e4f, 6); - d = a + rol32((b ^ (a | ~c)) + d + xf + 0xfe2ce6e0, 10); - c = d + rol32((a ^ (d | ~b)) + c + x6 + 0xa3014314, 15); - b = c + rol32((d ^ (c | ~a)) + b + xd + 0x4e0811a1, 21); - a = b + rol32((c ^ (b | ~d)) + a + x4 + 0xf7537e82, 6); - d = a + rol32((b ^ (a | ~c)) + d + xb + 0xbd3af235, 10); - c = d + rol32((a ^ (d | ~b)) + c + x2 + 0x2ad7d2bb, 15); - b = c + rol32((d ^ (c | ~a)) + b + x9 + 0xeb86d391, 21); - - this.#a = (this.#a + a) >>> 0; - this.#b = (this.#b + b) >>> 0; - this.#c = (this.#c + c) >>> 0; - this.#d = (this.#d + d) >>> 0; - } - - /** - * Update internal state - * @param data data to update, data cannot exceed 2^32 bytes - */ - update(data: Message): this { - let msg: Uint8Array; - - if (typeof data === "string") { - msg = new TextEncoder().encode(data as string); - } else if (typeof data === "object") { - if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) { - msg = new Uint8Array(data); - } else { - throw new Error(TYPE_ERROR_MSG); - } - } else { - throw new Error(TYPE_ERROR_MSG); - } - - let pos = this.#pos; - const free = BLOCK_SIZE - pos; - - if (msg.length < free) { - this.#block.set(msg, pos); - pos += msg.length; - } else { - // hash first block - this.#block.set(msg.slice(0, free), pos); - this.hash(this.#block); - - // hash as many blocks as possible - let i = free; - while (i + BLOCK_SIZE <= msg.length) { - this.hash(msg.slice(i, i + BLOCK_SIZE)); - i += BLOCK_SIZE; - } - - // store leftover - this.#block.fill(0).set(msg.slice(i), 0); - pos = msg.length - i; - } - - this.#pos = pos; - this.addLength(msg.length); - - return this; - } - - /** Returns final hash */ - digest(): ArrayBuffer { - let padLen = BLOCK_SIZE - this.#pos; - if (padLen < 9) padLen += BLOCK_SIZE; - - const pad = new Uint8Array(padLen); - - pad[0] = 0x80; - - const n0 = this.#n0 << 3; - const n1 = (this.#n1 << 3) | (this.#n0 >>> 29); - pad[pad.length - 8] = n0 & 0xff; - pad[pad.length - 7] = (n0 >>> 8) & 0xff; - pad[pad.length - 6] = (n0 >>> 16) & 0xff; - pad[pad.length - 5] = (n0 >>> 24) & 0xff; - pad[pad.length - 4] = n1 & 0xff; - pad[pad.length - 3] = (n1 >>> 8) & 0xff; - pad[pad.length - 2] = (n1 >>> 16) & 0xff; - pad[pad.length - 1] = (n1 >>> 24) & 0xff; - - this.update(pad.buffer); - - const hash = new ArrayBuffer(16); - const hashView = new DataView(hash); - hashView.setUint32(0, this.#a, true); - hashView.setUint32(4, this.#b, true); - hashView.setUint32(8, this.#c, true); - hashView.setUint32(12, this.#d, true); - - return hash; - } - - /** - * Returns hash as a string of given format - * @param format format of output string (hex or base64). Default is hex - */ - toString(format: "hex" | "base64" = "hex"): string { - const hash = this.digest(); - - switch (format) { - case "hex": - return hex.encodeToString(new Uint8Array(hash)); - case "base64": { - const data = new Uint8Array(hash); - let dataString = ""; - for (let i = 0; i < data.length; ++i) { - dataString += String.fromCharCode(data[i]); - } - return btoa(dataString); - } - default: - throw new Error("md5: invalid format"); - } - } -} diff --git a/std/hash/md5_test.ts b/std/hash/md5_test.ts deleted file mode 100644 index ebdc873dd..000000000 --- a/std/hash/md5_test.ts +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -import { assertEquals } from "../testing/asserts.ts"; -import { Md5 } from "./md5.ts"; - -const millionAs = "a".repeat(1000000); - -const testSetHex = [ - ["", "d41d8cd98f00b204e9800998ecf8427e"], - ["abc", "900150983cd24fb0d6963f7d28e17f72"], - ["deno", "c8772b401bc911da102a5291cc4ec83b"], - [ - "The quick brown fox jumps over the lazy dog", - "9e107d9d372bb6826bd81d3542a419d6", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "3b0c8ac703f828b04c6c197006d17218", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "014842d480b571495a4a0363793f7367", - ], - [millionAs, "7707d6ae4e027c70eea2a935c2296f21"], -]; - -const testSetBase64 = [ - ["", "1B2M2Y8AsgTpgAmY7PhCfg=="], - ["abc", "kAFQmDzST7DWlj99KOF/cg=="], - ["deno", "yHcrQBvJEdoQKlKRzE7IOw=="], - ["The quick brown fox jumps over the lazy dog", "nhB9nTcrtoJr2B01QqQZ1g=="], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "OwyKxwP4KLBMbBlwBtFyGA==", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "AUhC1IC1cUlaSgNjeT9zZw==", - ], - [millionAs, "dwfWrk4CfHDuoqk1wilvIQ=="], -]; - -Deno.test("[hash/md5] testMd5Hex", () => { - for (const [input, output] of testSetHex) { - const md5 = new Md5(); - assertEquals(md5.update(input).toString(), output); - } -}); - -Deno.test("[hash/md5] testMd5Base64", () => { - for (const [input, output] of testSetBase64) { - const md5 = new Md5(); - assertEquals(md5.update(input).toString("base64"), output); - } -}); diff --git a/std/hash/mod.ts b/std/hash/mod.ts deleted file mode 100644 index 7ab4dbbc4..000000000 --- a/std/hash/mod.ts +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -import { Hash } from "./_wasm/hash.ts"; -import type { Hasher } from "./hasher.ts"; - -export type { Hasher } from "./hasher.ts"; -export type SupportedAlgorithm = - | "md2" - | "md4" - | "md5" - | "ripemd160" - | "ripemd320" - | "sha1" - | "sha224" - | "sha256" - | "sha384" - | "sha512" - | "sha3-224" - | "sha3-256" - | "sha3-384" - | "sha3-512" - | "keccak224" - | "keccak256" - | "keccak384" - | "keccak512"; - -/** - * Creates a new `Hash` instance. - * - * @param algorithm name of hash algorithm to use - */ -export function createHash(algorithm: SupportedAlgorithm): Hasher { - return new Hash(algorithm as string); -} diff --git a/std/hash/sha1.ts b/std/hash/sha1.ts deleted file mode 100644 index 91b1f0de9..000000000 --- a/std/hash/sha1.ts +++ /dev/null @@ -1,454 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -/* - * [js-sha1]{@link https://github.com/emn178/js-sha1} - * - * @version 0.6.0 - * @author Chen, Yi-Cyuan [emn178@gmail.com] - * @copyright Chen, Yi-Cyuan 2014-2017 - * @license MIT - */ - -export type Message = string | number[] | ArrayBuffer; - -const HEX_CHARS = "0123456789abcdef".split(""); -const EXTRA = [-2147483648, 8388608, 32768, 128] as const; -const SHIFT = [24, 16, 8, 0] as const; - -const blocks: number[] = []; - -export class Sha1 { - #blocks!: number[]; - #block!: number; - #start!: number; - #bytes!: number; - #hBytes!: number; - #finalized!: boolean; - #hashed!: boolean; - - #h0 = 0x67452301; - #h1 = 0xefcdab89; - #h2 = 0x98badcfe; - #h3 = 0x10325476; - #h4 = 0xc3d2e1f0; - #lastByteIndex = 0; - - constructor(sharedMemory = false) { - this.init(sharedMemory); - } - protected init(sharedMemory: boolean) { - if (sharedMemory) { - // deno-fmt-ignore - blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; - this.#blocks = blocks; - } else { - this.#blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - } - - this.#h0 = 0x67452301; - this.#h1 = 0xefcdab89; - this.#h2 = 0x98badcfe; - this.#h3 = 0x10325476; - this.#h4 = 0xc3d2e1f0; - - this.#block = this.#start = this.#bytes = this.#hBytes = 0; - this.#finalized = this.#hashed = false; - } - update(message: Message): this { - if (this.#finalized) { - return this; - } - - let msg: string | number[] | Uint8Array | undefined; - if (message instanceof ArrayBuffer) { - msg = new Uint8Array(message); - } else { - msg = message; - } - - let index = 0; - const length = msg.length; - const blocks = this.#blocks; - - while (index < length) { - let i: number; - if (this.#hashed) { - this.#hashed = false; - blocks[0] = this.#block; - // deno-fmt-ignore - blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; - } - - if (typeof msg !== "string") { - for (i = this.#start; index < length && i < 64; ++index) { - blocks[i >> 2] |= msg[index] << SHIFT[i++ & 3]; - } - } else { - for (i = this.#start; index < length && i < 64; ++index) { - let code = msg.charCodeAt(index); - if (code < 0x80) { - blocks[i >> 2] |= code << SHIFT[i++ & 3]; - } else if (code < 0x800) { - blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } else if (code < 0xd800 || code >= 0xe000) { - blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } else { - code = 0x10000 + - (((code & 0x3ff) << 10) | (msg.charCodeAt(++index) & 0x3ff)); - blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } - } - } - - this.#lastByteIndex = i; - this.#bytes += i - this.#start; - if (i >= 64) { - this.#block = blocks[16]; - this.#start = i - 64; - this.hash(); - this.#hashed = true; - } else { - this.#start = i; - } - } - if (this.#bytes > 4294967295) { - this.#hBytes += (this.#bytes / 4294967296) >>> 0; - this.#bytes = this.#bytes >>> 0; - } - return this; - } - - protected finalize(): void { - if (this.#finalized) { - return; - } - this.#finalized = true; - const blocks = this.#blocks; - const i = this.#lastByteIndex; - blocks[16] = this.#block; - blocks[i >> 2] |= EXTRA[i & 3]; - this.#block = blocks[16]; - if (i >= 56) { - if (!this.#hashed) { - this.hash(); - } - blocks[0] = this.#block; - // deno-fmt-ignore - blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; - } - blocks[14] = (this.#hBytes << 3) | (this.#bytes >>> 29); - blocks[15] = this.#bytes << 3; - this.hash(); - } - - private hash(): void { - let a = this.#h0; - let b = this.#h1; - let c = this.#h2; - let d = this.#h3; - let e = this.#h4; - let f: number; - let j: number; - let t: number; - const blocks = this.#blocks; - - for (j = 16; j < 80; ++j) { - t = blocks[j - 3] ^ blocks[j - 8] ^ blocks[j - 14] ^ blocks[j - 16]; - blocks[j] = (t << 1) | (t >>> 31); - } - - for (j = 0; j < 20; j += 5) { - f = (b & c) | (~b & d); - t = (a << 5) | (a >>> 27); - e = (t + f + e + 1518500249 + blocks[j]) >>> 0; - b = (b << 30) | (b >>> 2); - - f = (a & b) | (~a & c); - t = (e << 5) | (e >>> 27); - d = (t + f + d + 1518500249 + blocks[j + 1]) >>> 0; - a = (a << 30) | (a >>> 2); - - f = (e & a) | (~e & b); - t = (d << 5) | (d >>> 27); - c = (t + f + c + 1518500249 + blocks[j + 2]) >>> 0; - e = (e << 30) | (e >>> 2); - - f = (d & e) | (~d & a); - t = (c << 5) | (c >>> 27); - b = (t + f + b + 1518500249 + blocks[j + 3]) >>> 0; - d = (d << 30) | (d >>> 2); - - f = (c & d) | (~c & e); - t = (b << 5) | (b >>> 27); - a = (t + f + a + 1518500249 + blocks[j + 4]) >>> 0; - c = (c << 30) | (c >>> 2); - } - - for (; j < 40; j += 5) { - f = b ^ c ^ d; - t = (a << 5) | (a >>> 27); - e = (t + f + e + 1859775393 + blocks[j]) >>> 0; - b = (b << 30) | (b >>> 2); - - f = a ^ b ^ c; - t = (e << 5) | (e >>> 27); - d = (t + f + d + 1859775393 + blocks[j + 1]) >>> 0; - a = (a << 30) | (a >>> 2); - - f = e ^ a ^ b; - t = (d << 5) | (d >>> 27); - c = (t + f + c + 1859775393 + blocks[j + 2]) >>> 0; - e = (e << 30) | (e >>> 2); - - f = d ^ e ^ a; - t = (c << 5) | (c >>> 27); - b = (t + f + b + 1859775393 + blocks[j + 3]) >>> 0; - d = (d << 30) | (d >>> 2); - - f = c ^ d ^ e; - t = (b << 5) | (b >>> 27); - a = (t + f + a + 1859775393 + blocks[j + 4]) >>> 0; - c = (c << 30) | (c >>> 2); - } - - for (; j < 60; j += 5) { - f = (b & c) | (b & d) | (c & d); - t = (a << 5) | (a >>> 27); - e = (t + f + e - 1894007588 + blocks[j]) >>> 0; - b = (b << 30) | (b >>> 2); - - f = (a & b) | (a & c) | (b & c); - t = (e << 5) | (e >>> 27); - d = (t + f + d - 1894007588 + blocks[j + 1]) >>> 0; - a = (a << 30) | (a >>> 2); - - f = (e & a) | (e & b) | (a & b); - t = (d << 5) | (d >>> 27); - c = (t + f + c - 1894007588 + blocks[j + 2]) >>> 0; - e = (e << 30) | (e >>> 2); - - f = (d & e) | (d & a) | (e & a); - t = (c << 5) | (c >>> 27); - b = (t + f + b - 1894007588 + blocks[j + 3]) >>> 0; - d = (d << 30) | (d >>> 2); - - f = (c & d) | (c & e) | (d & e); - t = (b << 5) | (b >>> 27); - a = (t + f + a - 1894007588 + blocks[j + 4]) >>> 0; - c = (c << 30) | (c >>> 2); - } - - for (; j < 80; j += 5) { - f = b ^ c ^ d; - t = (a << 5) | (a >>> 27); - e = (t + f + e - 899497514 + blocks[j]) >>> 0; - b = (b << 30) | (b >>> 2); - - f = a ^ b ^ c; - t = (e << 5) | (e >>> 27); - d = (t + f + d - 899497514 + blocks[j + 1]) >>> 0; - a = (a << 30) | (a >>> 2); - - f = e ^ a ^ b; - t = (d << 5) | (d >>> 27); - c = (t + f + c - 899497514 + blocks[j + 2]) >>> 0; - e = (e << 30) | (e >>> 2); - - f = d ^ e ^ a; - t = (c << 5) | (c >>> 27); - b = (t + f + b - 899497514 + blocks[j + 3]) >>> 0; - d = (d << 30) | (d >>> 2); - - f = c ^ d ^ e; - t = (b << 5) | (b >>> 27); - a = (t + f + a - 899497514 + blocks[j + 4]) >>> 0; - c = (c << 30) | (c >>> 2); - } - - this.#h0 = (this.#h0 + a) >>> 0; - this.#h1 = (this.#h1 + b) >>> 0; - this.#h2 = (this.#h2 + c) >>> 0; - this.#h3 = (this.#h3 + d) >>> 0; - this.#h4 = (this.#h4 + e) >>> 0; - } - - hex(): string { - this.finalize(); - - const h0 = this.#h0; - const h1 = this.#h1; - const h2 = this.#h2; - const h3 = this.#h3; - const h4 = this.#h4; - - return ( - HEX_CHARS[(h0 >> 28) & 0x0f] + - HEX_CHARS[(h0 >> 24) & 0x0f] + - HEX_CHARS[(h0 >> 20) & 0x0f] + - HEX_CHARS[(h0 >> 16) & 0x0f] + - HEX_CHARS[(h0 >> 12) & 0x0f] + - HEX_CHARS[(h0 >> 8) & 0x0f] + - HEX_CHARS[(h0 >> 4) & 0x0f] + - HEX_CHARS[h0 & 0x0f] + - HEX_CHARS[(h1 >> 28) & 0x0f] + - HEX_CHARS[(h1 >> 24) & 0x0f] + - HEX_CHARS[(h1 >> 20) & 0x0f] + - HEX_CHARS[(h1 >> 16) & 0x0f] + - HEX_CHARS[(h1 >> 12) & 0x0f] + - HEX_CHARS[(h1 >> 8) & 0x0f] + - HEX_CHARS[(h1 >> 4) & 0x0f] + - HEX_CHARS[h1 & 0x0f] + - HEX_CHARS[(h2 >> 28) & 0x0f] + - HEX_CHARS[(h2 >> 24) & 0x0f] + - HEX_CHARS[(h2 >> 20) & 0x0f] + - HEX_CHARS[(h2 >> 16) & 0x0f] + - HEX_CHARS[(h2 >> 12) & 0x0f] + - HEX_CHARS[(h2 >> 8) & 0x0f] + - HEX_CHARS[(h2 >> 4) & 0x0f] + - HEX_CHARS[h2 & 0x0f] + - HEX_CHARS[(h3 >> 28) & 0x0f] + - HEX_CHARS[(h3 >> 24) & 0x0f] + - HEX_CHARS[(h3 >> 20) & 0x0f] + - HEX_CHARS[(h3 >> 16) & 0x0f] + - HEX_CHARS[(h3 >> 12) & 0x0f] + - HEX_CHARS[(h3 >> 8) & 0x0f] + - HEX_CHARS[(h3 >> 4) & 0x0f] + - HEX_CHARS[h3 & 0x0f] + - HEX_CHARS[(h4 >> 28) & 0x0f] + - HEX_CHARS[(h4 >> 24) & 0x0f] + - HEX_CHARS[(h4 >> 20) & 0x0f] + - HEX_CHARS[(h4 >> 16) & 0x0f] + - HEX_CHARS[(h4 >> 12) & 0x0f] + - HEX_CHARS[(h4 >> 8) & 0x0f] + - HEX_CHARS[(h4 >> 4) & 0x0f] + - HEX_CHARS[h4 & 0x0f] - ); - } - - toString(): string { - return this.hex(); - } - - digest(): number[] { - this.finalize(); - - const h0 = this.#h0; - const h1 = this.#h1; - const h2 = this.#h2; - const h3 = this.#h3; - const h4 = this.#h4; - - return [ - (h0 >> 24) & 0xff, - (h0 >> 16) & 0xff, - (h0 >> 8) & 0xff, - h0 & 0xff, - (h1 >> 24) & 0xff, - (h1 >> 16) & 0xff, - (h1 >> 8) & 0xff, - h1 & 0xff, - (h2 >> 24) & 0xff, - (h2 >> 16) & 0xff, - (h2 >> 8) & 0xff, - h2 & 0xff, - (h3 >> 24) & 0xff, - (h3 >> 16) & 0xff, - (h3 >> 8) & 0xff, - h3 & 0xff, - (h4 >> 24) & 0xff, - (h4 >> 16) & 0xff, - (h4 >> 8) & 0xff, - h4 & 0xff, - ]; - } - - array(): number[] { - return this.digest(); - } - - arrayBuffer(): ArrayBuffer { - this.finalize(); - - const buffer = new ArrayBuffer(20); - const dataView = new DataView(buffer); - dataView.setUint32(0, this.#h0); - dataView.setUint32(4, this.#h1); - dataView.setUint32(8, this.#h2); - dataView.setUint32(12, this.#h3); - dataView.setUint32(16, this.#h4); - - return buffer; - } -} -export class HmacSha1 extends Sha1 { - #sharedMemory: boolean; - #inner: boolean; - #oKeyPad: number[]; - constructor(secretKey: Message, sharedMemory = false) { - super(sharedMemory); - let key: number[] | Uint8Array | undefined; - if (typeof secretKey === "string") { - const bytes: number[] = []; - const length: number = secretKey.length; - let index = 0; - for (let i = 0; i < length; i++) { - let code = secretKey.charCodeAt(i); - if (code < 0x80) { - bytes[index++] = code; - } else if (code < 0x800) { - bytes[index++] = 0xc0 | (code >> 6); - bytes[index++] = 0x80 | (code & 0x3f); - } else if (code < 0xd800 || code >= 0xe000) { - bytes[index++] = 0xe0 | (code >> 12); - bytes[index++] = 0x80 | ((code >> 6) & 0x3f); - bytes[index++] = 0x80 | (code & 0x3f); - } else { - code = 0x10000 + - (((code & 0x3ff) << 10) | (secretKey.charCodeAt(++i) & 0x3ff)); - bytes[index++] = 0xf0 | (code >> 18); - bytes[index++] = 0x80 | ((code >> 12) & 0x3f); - bytes[index++] = 0x80 | ((code >> 6) & 0x3f); - bytes[index++] = 0x80 | (code & 0x3f); - } - } - key = bytes; - } else { - if (secretKey instanceof ArrayBuffer) { - key = new Uint8Array(secretKey); - } else { - key = secretKey; - } - } - if (key.length > 64) { - key = new Sha1(true).update(key).array(); - } - const oKeyPad: number[] = []; - const iKeyPad: number[] = []; - for (let i = 0; i < 64; i++) { - const b = key[i] || 0; - oKeyPad[i] = 0x5c ^ b; - iKeyPad[i] = 0x36 ^ b; - } - - this.update(iKeyPad); - this.#oKeyPad = oKeyPad; - this.#inner = true; - this.#sharedMemory = sharedMemory; - } - protected finalize(): void { - super.finalize(); - if (this.#inner) { - this.#inner = false; - const innerHash = this.array(); - super.init(this.#sharedMemory); - this.update(this.#oKeyPad); - this.update(innerHash); - super.finalize(); - } - } -} diff --git a/std/hash/sha1_test.ts b/std/hash/sha1_test.ts deleted file mode 100644 index fc66df0bf..000000000 --- a/std/hash/sha1_test.ts +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -import { assertEquals } from "../testing/asserts.ts"; -import { HmacSha1, Message, Sha1 } from "./sha1.ts"; -import { dirname, fromFileUrl, join, resolve } from "../path/mod.ts"; - -const moduleDir = dirname(fromFileUrl(import.meta.url)); -const testdataDir = resolve(moduleDir, "testdata"); - -/** Handy function to convert an array/array buffer to a string of hex values. */ -function toHexString(value: number[] | ArrayBuffer): string { - const array = new Uint8Array(value); - let hex = ""; - for (const v of array) { - const c = v.toString(16); - hex += c.length === 1 ? `0${c}` : c; - } - return hex; -} - -// deno-fmt-ignore -const fixtures: { - sha1: Record<string, Record<string, Message>>; - sha1Hmac: Record<string, Record<string, [Message, Message]>>; -} = { - sha1: { - "ascii": { - "da39a3ee5e6b4b0d3255bfef95601890afd80709": "", - "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12": "The quick brown fox jumps over the lazy dog", - "408d94384216f890ff7a0c3528e8bed1e0b01621": "The quick brown fox jumps over the lazy dog." - }, - "ascii more than 64 bytes": { - "8690faab7755408a03875895176fac318f14a699": "The MD5 message-digest algorithm is a widely used cryptographic hash function producing a 128-bit (16-byte) hash value, typically expressed in text format as a 32 digit hexadecimal number. MD5 has been utilized in a wide variety of cryptographic applications, and is also commonly used to verify data integrity." - }, - "UTF8": { - "7be2d2d20c106eee0836c9bc2b939890a78e8fb3": "中文", - "9e4e5d978deced901d621475b03f1ded19e945bf": "aécio", - "4667688a63420661469c8dbc0f871770349bab08": "𠜎" - }, - "UTF8 more than 64 bytes": { - "ad8aae581c915fe01c4964a5e8b322cae74ee5c5": "訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一", - "3a15ad3ce9efdd4bf982eaaaecdeda36a887a3f9": "訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一(又譯雜湊演算法、摘要演算法等),主流程式語言普遍已有MD5的實作。" - }, - "special length": { - "4cdeae78e8b7285aef73e0a15eec7d5b30f3f3e3": "0123456780123456780123456780123456780123456780123456780", - "e657e6bb6b5d0c2bf7e929451c14a5302589a60b": "01234567801234567801234567801234567801234567801234567801", - "e7ad97591c1a99d54d80751d341899769884c75a": "0123456780123456780123456780123456780123456780123456780123456780", - "55a13698cdc010c0d16dab2f7dc10f43a713f12f": "01234567801234567801234567801234567801234567801234567801234567801234567", - "006575418c27b0158e55a6d261c46f86b33a496a": "012345678012345678012345678012345678012345678012345678012345678012345678" - }, - "Array": { - "da39a3ee5e6b4b0d3255bfef95601890afd80709": [], - '2fd4e1c67a2d28fced849ee1bb76e7391b93eb12': [84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103], - '55a13698cdc010c0d16dab2f7dc10f43a713f12f': [48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55] - }, - "Uint8Array": { - '2fd4e1c67a2d28fced849ee1bb76e7391b93eb12': new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]) - }, - "Int8Array": { - '2fd4e1c67a2d28fced849ee1bb76e7391b93eb12': new Int8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]) - }, - "ArrayBuffer": { - '5ba93c9db0cff93f52b521d7420e43f6eda2784f': new ArrayBuffer(1) - } - }, - sha1Hmac:{ - - "Test Vectors": { - "b617318655057264e28bc0b6fb378c8ef146be00": [ - [0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b], - "Hi There" - ], - "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79": [ - "Jefe", - "what do ya want for nothing?" - ], - "125d7342b9ac11cd91a39af48aa17b4f63f175d3": [ - [0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa], - [0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd] - ], - "4c9007f4026250c6bc8414f9bf50c86c2d7235da": [ - [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19], - [0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd] - ], - "90d0dace1c1bdc957339307803160335bde6df2b": [ - [0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa], - "Test Using Larger Than Block-Size Key - Hash Key First" - ], - "217e44bb08b6e06a2d6c30f3cb9f537f97c63356": [ - [0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa], - "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm." - ] - }, - "UTF8": { - "f495de6d0f1b5681070a024bbaed5b5f42847306": ["中文", "中文"], - "58891d68487ffebddba5925abedec77a5a578db2": ["aécio", "aécio"], - "a1816bff2dae324c283aeab564d5edb5170fbada": ["𠜎", "𠜎"] - } - }, -}; - -const methods = ["array", "arrayBuffer", "digest", "hex"] as const; - -for (const method of methods) { - for (const [name, tests] of Object.entries(fixtures.sha1)) { - let i = 1; - for (const [expected, message] of Object.entries(tests)) { - Deno.test({ - name: `sha1.${method}() - ${name} - #${i++}`, - fn() { - const algorithm = new Sha1(); - algorithm.update(message); - const actual = method === "hex" - ? algorithm[method]() - : toHexString(algorithm[method]()); - assertEquals(actual, expected); - }, - }); - } - } -} - -for (const method of methods) { - for (const [name, tests] of Object.entries(fixtures.sha1)) { - let i = 1; - for (const [expected, message] of Object.entries(tests)) { - Deno.test({ - name: `sha1.${method}() - ${name} - #${i++}`, - fn() { - const algorithm = new Sha1(true); - algorithm.update(message); - const actual = method === "hex" - ? algorithm[method]() - : toHexString(algorithm[method]()); - assertEquals(actual, expected); - }, - }); - } - } -} - -for (const method of methods) { - for (const [name, tests] of Object.entries(fixtures.sha1Hmac)) { - let i = 1; - for (const [expected, [key, message]] of Object.entries(tests)) { - Deno.test({ - name: `hmacSha1.${method}() - ${name} - #${i++}`, - fn() { - const algorithm = new HmacSha1(key); - algorithm.update(message); - const actual = method === "hex" - ? algorithm[method]() - : toHexString(algorithm[method]()); - assertEquals(actual, expected); - }, - }); - } - } -} - -Deno.test("[hash/sha1] test Uint8Array from Reader", async () => { - const data = await Deno.readFile(join(testdataDir, "hashtest")); - - const hash = new Sha1().update(data).hex(); - assertEquals(hash, "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"); -}); diff --git a/std/hash/sha256.ts b/std/hash/sha256.ts deleted file mode 100644 index a566f838a..000000000 --- a/std/hash/sha256.ts +++ /dev/null @@ -1,543 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -/* - * Adapted to deno from: - * - * [js-sha256]{@link https://github.com/emn178/js-sha256} - * - * @version 0.9.0 - * @author Chen, Yi-Cyuan [emn178@gmail.com] - * @copyright Chen, Yi-Cyuan 2014-2017 - * @license MIT - */ - -export type Message = string | number[] | ArrayBuffer; - -const HEX_CHARS = "0123456789abcdef".split(""); -const EXTRA = [-2147483648, 8388608, 32768, 128] as const; -const SHIFT = [24, 16, 8, 0] as const; -// deno-fmt-ignore -const K = [ - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, - 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, - 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, - 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, - 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, - 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, - 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, - 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, - 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, -] as const; - -const blocks: number[] = []; - -export class Sha256 { - #block!: number; - #blocks!: number[]; - #bytes!: number; - #finalized!: boolean; - #first!: boolean; - #h0!: number; - #h1!: number; - #h2!: number; - #h3!: number; - #h4!: number; - #h5!: number; - #h6!: number; - #h7!: number; - #hashed!: boolean; - #hBytes!: number; - #is224!: boolean; - #lastByteIndex = 0; - #start!: number; - - constructor(is224 = false, sharedMemory = false) { - this.init(is224, sharedMemory); - } - - protected init(is224: boolean, sharedMemory: boolean): void { - if (sharedMemory) { - // deno-fmt-ignore - blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; - this.#blocks = blocks; - } else { - this.#blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - } - - if (is224) { - this.#h0 = 0xc1059ed8; - this.#h1 = 0x367cd507; - this.#h2 = 0x3070dd17; - this.#h3 = 0xf70e5939; - this.#h4 = 0xffc00b31; - this.#h5 = 0x68581511; - this.#h6 = 0x64f98fa7; - this.#h7 = 0xbefa4fa4; - } else { - // 256 - this.#h0 = 0x6a09e667; - this.#h1 = 0xbb67ae85; - this.#h2 = 0x3c6ef372; - this.#h3 = 0xa54ff53a; - this.#h4 = 0x510e527f; - this.#h5 = 0x9b05688c; - this.#h6 = 0x1f83d9ab; - this.#h7 = 0x5be0cd19; - } - - this.#block = this.#start = this.#bytes = this.#hBytes = 0; - this.#finalized = this.#hashed = false; - this.#first = true; - this.#is224 = is224; - } - - /** Update hash - * - * @param message The message you want to hash. - */ - update(message: Message): this { - if (this.#finalized) { - return this; - } - - let msg: string | number[] | Uint8Array | undefined; - if (message instanceof ArrayBuffer) { - msg = new Uint8Array(message); - } else { - msg = message; - } - - let index = 0; - const length = msg.length; - const blocks = this.#blocks; - - while (index < length) { - let i: number; - if (this.#hashed) { - this.#hashed = false; - blocks[0] = this.#block; - // deno-fmt-ignore - blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; - } - - if (typeof msg !== "string") { - for (i = this.#start; index < length && i < 64; ++index) { - blocks[i >> 2] |= msg[index] << SHIFT[i++ & 3]; - } - } else { - for (i = this.#start; index < length && i < 64; ++index) { - let code = msg.charCodeAt(index); - if (code < 0x80) { - blocks[i >> 2] |= code << SHIFT[i++ & 3]; - } else if (code < 0x800) { - blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } else if (code < 0xd800 || code >= 0xe000) { - blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } else { - code = 0x10000 + - (((code & 0x3ff) << 10) | (msg.charCodeAt(++index) & 0x3ff)); - blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } - } - } - - this.#lastByteIndex = i; - this.#bytes += i - this.#start; - if (i >= 64) { - this.#block = blocks[16]; - this.#start = i - 64; - this.hash(); - this.#hashed = true; - } else { - this.#start = i; - } - } - if (this.#bytes > 4294967295) { - this.#hBytes += (this.#bytes / 4294967296) << 0; - this.#bytes = this.#bytes % 4294967296; - } - return this; - } - - protected finalize(): void { - if (this.#finalized) { - return; - } - this.#finalized = true; - const blocks = this.#blocks; - const i = this.#lastByteIndex; - blocks[16] = this.#block; - blocks[i >> 2] |= EXTRA[i & 3]; - this.#block = blocks[16]; - if (i >= 56) { - if (!this.#hashed) { - this.hash(); - } - blocks[0] = this.#block; - // deno-fmt-ignore - blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; - } - blocks[14] = (this.#hBytes << 3) | (this.#bytes >>> 29); - blocks[15] = this.#bytes << 3; - this.hash(); - } - - protected hash(): void { - let a = this.#h0; - let b = this.#h1; - let c = this.#h2; - let d = this.#h3; - let e = this.#h4; - let f = this.#h5; - let g = this.#h6; - let h = this.#h7; - const blocks = this.#blocks; - let s0: number; - let s1: number; - let maj: number; - let t1: number; - let t2: number; - let ch: number; - let ab: number; - let da: number; - let cd: number; - let bc: number; - - for (let j = 16; j < 64; ++j) { - // rightrotate - t1 = blocks[j - 15]; - s0 = ((t1 >>> 7) | (t1 << 25)) ^ ((t1 >>> 18) | (t1 << 14)) ^ (t1 >>> 3); - t1 = blocks[j - 2]; - s1 = ((t1 >>> 17) | (t1 << 15)) ^ ((t1 >>> 19) | (t1 << 13)) ^ - (t1 >>> 10); - blocks[j] = (blocks[j - 16] + s0 + blocks[j - 7] + s1) << 0; - } - - bc = b & c; - for (let j = 0; j < 64; j += 4) { - if (this.#first) { - if (this.#is224) { - ab = 300032; - t1 = blocks[0] - 1413257819; - h = (t1 - 150054599) << 0; - d = (t1 + 24177077) << 0; - } else { - ab = 704751109; - t1 = blocks[0] - 210244248; - h = (t1 - 1521486534) << 0; - d = (t1 + 143694565) << 0; - } - this.#first = false; - } else { - s0 = ((a >>> 2) | (a << 30)) ^ - ((a >>> 13) | (a << 19)) ^ - ((a >>> 22) | (a << 10)); - s1 = ((e >>> 6) | (e << 26)) ^ - ((e >>> 11) | (e << 21)) ^ - ((e >>> 25) | (e << 7)); - ab = a & b; - maj = ab ^ (a & c) ^ bc; - ch = (e & f) ^ (~e & g); - t1 = h + s1 + ch + K[j] + blocks[j]; - t2 = s0 + maj; - h = (d + t1) << 0; - d = (t1 + t2) << 0; - } - s0 = ((d >>> 2) | (d << 30)) ^ - ((d >>> 13) | (d << 19)) ^ - ((d >>> 22) | (d << 10)); - s1 = ((h >>> 6) | (h << 26)) ^ - ((h >>> 11) | (h << 21)) ^ - ((h >>> 25) | (h << 7)); - da = d & a; - maj = da ^ (d & b) ^ ab; - ch = (h & e) ^ (~h & f); - t1 = g + s1 + ch + K[j + 1] + blocks[j + 1]; - t2 = s0 + maj; - g = (c + t1) << 0; - c = (t1 + t2) << 0; - s0 = ((c >>> 2) | (c << 30)) ^ - ((c >>> 13) | (c << 19)) ^ - ((c >>> 22) | (c << 10)); - s1 = ((g >>> 6) | (g << 26)) ^ - ((g >>> 11) | (g << 21)) ^ - ((g >>> 25) | (g << 7)); - cd = c & d; - maj = cd ^ (c & a) ^ da; - ch = (g & h) ^ (~g & e); - t1 = f + s1 + ch + K[j + 2] + blocks[j + 2]; - t2 = s0 + maj; - f = (b + t1) << 0; - b = (t1 + t2) << 0; - s0 = ((b >>> 2) | (b << 30)) ^ - ((b >>> 13) | (b << 19)) ^ - ((b >>> 22) | (b << 10)); - s1 = ((f >>> 6) | (f << 26)) ^ - ((f >>> 11) | (f << 21)) ^ - ((f >>> 25) | (f << 7)); - bc = b & c; - maj = bc ^ (b & d) ^ cd; - ch = (f & g) ^ (~f & h); - t1 = e + s1 + ch + K[j + 3] + blocks[j + 3]; - t2 = s0 + maj; - e = (a + t1) << 0; - a = (t1 + t2) << 0; - } - - this.#h0 = (this.#h0 + a) << 0; - this.#h1 = (this.#h1 + b) << 0; - this.#h2 = (this.#h2 + c) << 0; - this.#h3 = (this.#h3 + d) << 0; - this.#h4 = (this.#h4 + e) << 0; - this.#h5 = (this.#h5 + f) << 0; - this.#h6 = (this.#h6 + g) << 0; - this.#h7 = (this.#h7 + h) << 0; - } - - /** Return hash in hex string. */ - hex(): string { - this.finalize(); - - const h0 = this.#h0; - const h1 = this.#h1; - const h2 = this.#h2; - const h3 = this.#h3; - const h4 = this.#h4; - const h5 = this.#h5; - const h6 = this.#h6; - const h7 = this.#h7; - - let hex = HEX_CHARS[(h0 >> 28) & 0x0f] + - HEX_CHARS[(h0 >> 24) & 0x0f] + - HEX_CHARS[(h0 >> 20) & 0x0f] + - HEX_CHARS[(h0 >> 16) & 0x0f] + - HEX_CHARS[(h0 >> 12) & 0x0f] + - HEX_CHARS[(h0 >> 8) & 0x0f] + - HEX_CHARS[(h0 >> 4) & 0x0f] + - HEX_CHARS[h0 & 0x0f] + - HEX_CHARS[(h1 >> 28) & 0x0f] + - HEX_CHARS[(h1 >> 24) & 0x0f] + - HEX_CHARS[(h1 >> 20) & 0x0f] + - HEX_CHARS[(h1 >> 16) & 0x0f] + - HEX_CHARS[(h1 >> 12) & 0x0f] + - HEX_CHARS[(h1 >> 8) & 0x0f] + - HEX_CHARS[(h1 >> 4) & 0x0f] + - HEX_CHARS[h1 & 0x0f] + - HEX_CHARS[(h2 >> 28) & 0x0f] + - HEX_CHARS[(h2 >> 24) & 0x0f] + - HEX_CHARS[(h2 >> 20) & 0x0f] + - HEX_CHARS[(h2 >> 16) & 0x0f] + - HEX_CHARS[(h2 >> 12) & 0x0f] + - HEX_CHARS[(h2 >> 8) & 0x0f] + - HEX_CHARS[(h2 >> 4) & 0x0f] + - HEX_CHARS[h2 & 0x0f] + - HEX_CHARS[(h3 >> 28) & 0x0f] + - HEX_CHARS[(h3 >> 24) & 0x0f] + - HEX_CHARS[(h3 >> 20) & 0x0f] + - HEX_CHARS[(h3 >> 16) & 0x0f] + - HEX_CHARS[(h3 >> 12) & 0x0f] + - HEX_CHARS[(h3 >> 8) & 0x0f] + - HEX_CHARS[(h3 >> 4) & 0x0f] + - HEX_CHARS[h3 & 0x0f] + - HEX_CHARS[(h4 >> 28) & 0x0f] + - HEX_CHARS[(h4 >> 24) & 0x0f] + - HEX_CHARS[(h4 >> 20) & 0x0f] + - HEX_CHARS[(h4 >> 16) & 0x0f] + - HEX_CHARS[(h4 >> 12) & 0x0f] + - HEX_CHARS[(h4 >> 8) & 0x0f] + - HEX_CHARS[(h4 >> 4) & 0x0f] + - HEX_CHARS[h4 & 0x0f] + - HEX_CHARS[(h5 >> 28) & 0x0f] + - HEX_CHARS[(h5 >> 24) & 0x0f] + - HEX_CHARS[(h5 >> 20) & 0x0f] + - HEX_CHARS[(h5 >> 16) & 0x0f] + - HEX_CHARS[(h5 >> 12) & 0x0f] + - HEX_CHARS[(h5 >> 8) & 0x0f] + - HEX_CHARS[(h5 >> 4) & 0x0f] + - HEX_CHARS[h5 & 0x0f] + - HEX_CHARS[(h6 >> 28) & 0x0f] + - HEX_CHARS[(h6 >> 24) & 0x0f] + - HEX_CHARS[(h6 >> 20) & 0x0f] + - HEX_CHARS[(h6 >> 16) & 0x0f] + - HEX_CHARS[(h6 >> 12) & 0x0f] + - HEX_CHARS[(h6 >> 8) & 0x0f] + - HEX_CHARS[(h6 >> 4) & 0x0f] + - HEX_CHARS[h6 & 0x0f]; - if (!this.#is224) { - hex += HEX_CHARS[(h7 >> 28) & 0x0f] + - HEX_CHARS[(h7 >> 24) & 0x0f] + - HEX_CHARS[(h7 >> 20) & 0x0f] + - HEX_CHARS[(h7 >> 16) & 0x0f] + - HEX_CHARS[(h7 >> 12) & 0x0f] + - HEX_CHARS[(h7 >> 8) & 0x0f] + - HEX_CHARS[(h7 >> 4) & 0x0f] + - HEX_CHARS[h7 & 0x0f]; - } - return hex; - } - - /** Return hash in hex string. */ - toString(): string { - return this.hex(); - } - - /** Return hash in integer array. */ - digest(): number[] { - this.finalize(); - - const h0 = this.#h0; - const h1 = this.#h1; - const h2 = this.#h2; - const h3 = this.#h3; - const h4 = this.#h4; - const h5 = this.#h5; - const h6 = this.#h6; - const h7 = this.#h7; - - const arr = [ - (h0 >> 24) & 0xff, - (h0 >> 16) & 0xff, - (h0 >> 8) & 0xff, - h0 & 0xff, - (h1 >> 24) & 0xff, - (h1 >> 16) & 0xff, - (h1 >> 8) & 0xff, - h1 & 0xff, - (h2 >> 24) & 0xff, - (h2 >> 16) & 0xff, - (h2 >> 8) & 0xff, - h2 & 0xff, - (h3 >> 24) & 0xff, - (h3 >> 16) & 0xff, - (h3 >> 8) & 0xff, - h3 & 0xff, - (h4 >> 24) & 0xff, - (h4 >> 16) & 0xff, - (h4 >> 8) & 0xff, - h4 & 0xff, - (h5 >> 24) & 0xff, - (h5 >> 16) & 0xff, - (h5 >> 8) & 0xff, - h5 & 0xff, - (h6 >> 24) & 0xff, - (h6 >> 16) & 0xff, - (h6 >> 8) & 0xff, - h6 & 0xff, - ]; - if (!this.#is224) { - arr.push( - (h7 >> 24) & 0xff, - (h7 >> 16) & 0xff, - (h7 >> 8) & 0xff, - h7 & 0xff, - ); - } - return arr; - } - - /** Return hash in integer array. */ - array(): number[] { - return this.digest(); - } - - /** Return hash in ArrayBuffer. */ - arrayBuffer(): ArrayBuffer { - this.finalize(); - - const buffer = new ArrayBuffer(this.#is224 ? 28 : 32); - const dataView = new DataView(buffer); - dataView.setUint32(0, this.#h0); - dataView.setUint32(4, this.#h1); - dataView.setUint32(8, this.#h2); - dataView.setUint32(12, this.#h3); - dataView.setUint32(16, this.#h4); - dataView.setUint32(20, this.#h5); - dataView.setUint32(24, this.#h6); - if (!this.#is224) { - dataView.setUint32(28, this.#h7); - } - return buffer; - } -} - -export class HmacSha256 extends Sha256 { - #inner: boolean; - #is224: boolean; - #oKeyPad: number[]; - #sharedMemory: boolean; - - constructor(secretKey: Message, is224 = false, sharedMemory = false) { - super(is224, sharedMemory); - - let key: number[] | Uint8Array | undefined; - if (typeof secretKey === "string") { - const bytes: number[] = []; - const length = secretKey.length; - let index = 0; - for (let i = 0; i < length; ++i) { - let code = secretKey.charCodeAt(i); - if (code < 0x80) { - bytes[index++] = code; - } else if (code < 0x800) { - bytes[index++] = 0xc0 | (code >> 6); - bytes[index++] = 0x80 | (code & 0x3f); - } else if (code < 0xd800 || code >= 0xe000) { - bytes[index++] = 0xe0 | (code >> 12); - bytes[index++] = 0x80 | ((code >> 6) & 0x3f); - bytes[index++] = 0x80 | (code & 0x3f); - } else { - code = 0x10000 + - (((code & 0x3ff) << 10) | (secretKey.charCodeAt(++i) & 0x3ff)); - bytes[index++] = 0xf0 | (code >> 18); - bytes[index++] = 0x80 | ((code >> 12) & 0x3f); - bytes[index++] = 0x80 | ((code >> 6) & 0x3f); - bytes[index++] = 0x80 | (code & 0x3f); - } - } - key = bytes; - } else { - if (secretKey instanceof ArrayBuffer) { - key = new Uint8Array(secretKey); - } else { - key = secretKey; - } - } - - if (key.length > 64) { - key = new Sha256(is224, true).update(key).array(); - } - - const oKeyPad: number[] = []; - const iKeyPad: number[] = []; - for (let i = 0; i < 64; ++i) { - const b = key[i] || 0; - oKeyPad[i] = 0x5c ^ b; - iKeyPad[i] = 0x36 ^ b; - } - - this.update(iKeyPad); - this.#oKeyPad = oKeyPad; - this.#inner = true; - this.#is224 = is224; - this.#sharedMemory = sharedMemory; - } - - protected finalize(): void { - super.finalize(); - if (this.#inner) { - this.#inner = false; - const innerHash = this.array(); - super.init(this.#is224, this.#sharedMemory); - this.update(this.#oKeyPad); - this.update(innerHash); - super.finalize(); - } - } -} diff --git a/std/hash/sha256_test.ts b/std/hash/sha256_test.ts deleted file mode 100644 index 1ca929223..000000000 --- a/std/hash/sha256_test.ts +++ /dev/null @@ -1,297 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -import { HmacSha256, Message, Sha256 } from "./sha256.ts"; -import { assertEquals } from "../testing/asserts.ts"; -import { dirname, fromFileUrl, join, resolve } from "../path/mod.ts"; - -const moduleDir = dirname(fromFileUrl(import.meta.url)); -const testdataDir = resolve(moduleDir, "testdata"); - -/** Handy function to convert an array/array buffer to a string of hex values. */ -function toHexString(value: number[] | ArrayBuffer): string { - const array = new Uint8Array(value); - let hex = ""; - for (const v of array) { - const c = v.toString(16); - hex += c.length === 1 ? `0${c}` : c; - } - return hex; -} - -// deno-fmt-ignore -const fixtures: { - sha256: Record<string, Record<string, Message>>; - sha224: Record<string, Record<string, Message>>; - sha256Hmac: Record<string, Record<string, [Message, Message]>>; - sha224Hmac: Record<string, Record<string, [Message, Message]>>; -} = { - sha256: { - "ascii": { - "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855": "", - "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592": "The quick brown fox jumps over the lazy dog", - "ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c": "The quick brown fox jumps over the lazy dog." - }, - "ascii more than 64 bytes": { - "54e73d89e1924fdcd056390266a983924b6d6d461e9470b6cd50bbaf69b5c54c": "The MD5 message-digest algorithm is a widely used cryptographic hash function producing a 128-bit (16-byte) hash value, typically expressed in text format as a 32 digit hexadecimal number. MD5 has been utilized in a wide variety of cryptographic applications, and is also commonly used to verify data integrity." - }, - "UTF8": { - "72726d8818f693066ceb69afa364218b692e62ea92b385782363780f47529c21": "中文", - "53196d1acfce0c4b264e01e8018c989d571351f59e33f055f76ff15b4f0516c6": "aécio", - "8d10a48685dbc34484696de7ea7434d80a54c1d60100530faccf697463ef19c9": "𠜎" - }, - "UTF8 more than 64 bytes": { - "d691014feebf35b3500ef6f6738d0094cac63628a7a018a980a40292a77703d1": "訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一", - "81a1472ebdeb09406a783d607ff49ee2fde3e9f44ac1cd158ad8d6ad3c4e69fa": "訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一(又譯雜湊演算法、摘要演算法等),主流程式語言普遍已有MD5的實作。" - }, - "special length": { - "5e6b963e2b6444dab8544beab8532850cef2a9d143872a6a5384abe37e61b3db": "0123456780123456780123456780123456780123456780123456780", - "85d240a4a03a0710423fc4f701da51e8785c9eaa96d718ab1c7991d6afd60d62": "01234567801234567801234567801234567801234567801234567801", - "c3ee464d5620eb2dde3dfda4c7955dbd9e9e2e9b113c13983fc67b0dfd892a53": "0123456780123456780123456780123456780123456780123456780123456780", - "74b51c6911f9a8b5e7c499effe7604e43b672166818873c27752c248de434841": "01234567801234567801234567801234567801234567801234567801234567801234567", - "6fba9e623ae6abf028a1b195748814aa95eebfb22e3ec5e15d2444cd6c48186a": "012345678012345678012345678012345678012345678012345678012345678012345678" - }, - "Array": { - "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855": [], - "182889f925ae4e5cc37118ded6ed87f7bdc7cab5ec5e78faef2e50048999473f": [211, 212], - "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592": [84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103], - "74b51c6911f9a8b5e7c499effe7604e43b672166818873c27752c248de434841": [48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55] - } - }, - sha224: { - "ascii": { - "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f": "", - "730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525": "The quick brown fox jumps over the lazy dog", - "619cba8e8e05826e9b8c519c0a5c68f4fb653e8a3d8aa04bb2c8cd4c": "The quick brown fox jumps over the lazy dog." - }, - "ascii more than 64 bytes": { - "4d97e15967391d2e846ea7d21bb480efadbae5868b731e7cc6267006": "The MD5 message-digest algorithm is a widely used cryptographic hash function producing a 128-bit (16-byte) hash value, typically expressed in text format as a 32 digit hexadecimal number. MD5 has been utilized in a wide variety of cryptographic applications, and is also commonly used to verify data integrity." - }, - "UTF8": { - "dfbab71afdf54388af4d55f8bd3de8c9b15e0eb916bf9125f4a959d4": "中文", - "d12841cafd89c534924a839e62bf35a2b5f3717b7802eb19bd8d8e15": "aécio", - "eaa0129b5509f5701db218fb7076b282e4409da52d06363aa3bdd63d": "𠜎" - }, - "UTF8 more than 64 bytes": { - "0dda421f3f81272418e1313673e9d74b7f2d04efc9c52c69458e12c3": "訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一", - "a8cb74a54e6dc6ab6110db3915ba08ffe5e1abafaea78538fa12a626": "訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一(又譯雜湊演算法、摘要演算法等),主流程式語言普遍已有MD5的實作。" - }, - "special length": { - "bc4a354d66f3cff4bc6dd6a88fbb0435cede7fd5fe94da0760cb1924": "0123456780123456780123456780123456780123456780123456780", - "2f148f757d1295784a7c69bf328b8bf827a536669e132234cd6f50e7": "01234567801234567801234567801234567801234567801234567801", - "496275a96bf41aa27ce89c3ae0fc63c3a3eab063887a8ea075bd091b": "0123456780123456780123456780123456780123456780123456780123456780", - "16ee1b101fe0e0d8dd156d598931ec19d75b0f8dc0a0455733c168c8": "01234567801234567801234567801234567801234567801234567801234567801234567", - "04c7a30079c640e440d884cdf0d7ab04fd05501d4498cb21be29ca1f": "012345678012345678012345678012345678012345678012345678012345678012345678" - }, - "Array": { - "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f": [], - "730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525": [84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103], - "16ee1b101fe0e0d8dd156d598931ec19d75b0f8dc0a0455733c168c8": [48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55] - } - }, - sha256Hmac: { - "Test Vectors": { - "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7": [ - [0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b], - "Hi There" - ], - "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843": [ - "Jefe", - "what do ya want for nothing?" - ], - "773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe": [ - [0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa], - [0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd] - ], - "82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b": [ - [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19], - [0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd] - ], - "60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54": [ - [0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa], - "Test Using Larger Than Block-Size Key - Hash Key First" - ], - "9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2": [ - [0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa], - "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm." - ] - }, - "UTF8": { - "865cc329d317f6d9fdbd183a3c5cc5fd4c370d11f98abbbb404bceb1e6392c7e": ["中文", "中文"], - "efeef87be5731506b69bb64a9898a456dd12c94834c36a4d8ba99e3db79ad7ed": ["aécio", "aécio"], - "8a6e527049b9cfc7e1c84bcf356a1289c95da68a586c03de3327f3de0d3737fe": ["𠜎", "𠜎"] - } - }, - sha224Hmac: { - "Test Vectors": { - "896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22": [ - [0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b], - "Hi There" - ], - "a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44": [ - "Jefe", - "what do ya want for nothing?" - ], - "7fb3cb3588c6c1f6ffa9694d7d6ad2649365b0c1f65d69d1ec8333ea": [ - [0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa], - [0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd] - ], - "6c11506874013cac6a2abc1bb382627cec6a90d86efc012de7afec5a": [ - [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19], - [0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd] - ], - "95e9a0db962095adaebe9b2d6f0dbce2d499f112f2d2b7273fa6870e": [ - [0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa], - "Test Using Larger Than Block-Size Key - Hash Key First" - ], - "3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1": [ - [0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa], - "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm." - ] - }, - "UTF8": { - "e2280928fe813aeb7fa59aa14dd5e589041bfdf91945d19d25b9f3db": ["中文", "中文"], - "86c53dc054b16f6e006a254891bc9ff0da5df8e1a6faee3b0aaa732d": ["aécio", "aécio"], - "e9e5991bfb84506b105f800afac1599ff807bb8e20db8ffda48997b9": ["𠜎", "𠜎"] - } - }, -}; - -// deno-fmt-ignore -fixtures.sha256.Uint8Array = { - '182889f925ae4e5cc37118ded6ed87f7bdc7cab5ec5e78faef2e50048999473f': new Uint8Array([211, 212]), - 'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592': new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]) -}; -// deno-fmt-ignore -fixtures.sha256.Int8Array = { - 'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592': new Int8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]) -}; -// deno-fmt-ignore -fixtures.sha256.ArrayBuffer = { - 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855': new ArrayBuffer(0), - '6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d': new ArrayBuffer(1) -}; -// deno-fmt-ignore -fixtures.sha224.Uint8Array = { - 'e17541396a3ecd1cd5a2b968b84e597e8eae3b0ea3127963bf48dd3b': new Uint8Array([211, 212]), - '730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525': new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]) -}; -// deno-fmt-ignore -fixtures.sha224.Int8Array = { - '730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525': new Int8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]) -}; -// deno-fmt-ignore -fixtures.sha224.ArrayBuffer = { - 'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f': new ArrayBuffer(0), - 'fff9292b4201617bdc4d3053fce02734166a683d7d858a7f5f59b073': new ArrayBuffer(1), -}; -fixtures.sha256Hmac.Uint8Array = { - e48411262715c8370cd5e7bf8e82bef53bd53712d007f3429351843b77c7bb9b: [ - new Uint8Array(0), - "Hi There", - ], -}; -fixtures.sha256Hmac.ArrayBuffer = { - e48411262715c8370cd5e7bf8e82bef53bd53712d007f3429351843b77c7bb9b: [ - new ArrayBuffer(0), - "Hi There", - ], -}; -fixtures.sha224Hmac.Uint8Array = { - da8f94de91d62154b55ea4e8d6eb133f6d553bcd1f1ba205b9488945: [ - new Uint8Array(0), - "Hi There", - ], -}; -fixtures.sha224Hmac.ArrayBuffer = { - da8f94de91d62154b55ea4e8d6eb133f6d553bcd1f1ba205b9488945: [ - new ArrayBuffer(0), - "Hi There", - ], -}; - -const methods = ["array", "arrayBuffer", "digest", "hex"] as const; - -for (const method of methods) { - for (const [name, tests] of Object.entries(fixtures.sha256)) { - let i = 1; - for (const [expected, message] of Object.entries(tests)) { - Deno.test({ - name: `sha256.${method}() - ${name} - #${i++}`, - fn() { - const algorithm = new Sha256(); - algorithm.update(message); - const actual = method === "hex" - ? algorithm[method]() - : toHexString(algorithm[method]()); - assertEquals(actual, expected); - }, - }); - } - } -} - -for (const method of methods) { - for (const [name, tests] of Object.entries(fixtures.sha224)) { - let i = 1; - for (const [expected, message] of Object.entries(tests)) { - Deno.test({ - name: `sha224.${method}() - ${name} - #${i++}`, - fn() { - const algorithm = new Sha256(true); - algorithm.update(message); - const actual = method === "hex" - ? algorithm[method]() - : toHexString(algorithm[method]()); - assertEquals(actual, expected); - }, - }); - } - } -} - -for (const method of methods) { - for (const [name, tests] of Object.entries(fixtures.sha256Hmac)) { - let i = 1; - for (const [expected, [key, message]] of Object.entries(tests)) { - Deno.test({ - name: `hmacSha256.${method}() - ${name} - #${i++}`, - fn() { - const algorithm = new HmacSha256(key); - algorithm.update(message); - const actual = method === "hex" - ? algorithm[method]() - : toHexString(algorithm[method]()); - assertEquals(actual, expected); - }, - }); - } - } -} - -for (const method of methods) { - for (const [name, tests] of Object.entries(fixtures.sha224Hmac)) { - let i = 1; - for (const [expected, [key, message]] of Object.entries(tests)) { - Deno.test({ - name: `hmacSha224.${method}() - ${name} - #${i++}`, - fn() { - const algorithm = new HmacSha256(key, true); - algorithm.update(message); - const actual = method === "hex" - ? algorithm[method]() - : toHexString(algorithm[method]()); - assertEquals(actual, expected); - }, - }); - } - } -} - -Deno.test("[hash/sha256] test Uint8Array from Reader", async () => { - const data = await Deno.readFile(join(testdataDir, "hashtest")); - - const hash = new Sha256().update(data).hex(); - assertEquals( - hash, - "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08", - ); -}); diff --git a/std/hash/sha3.ts b/std/hash/sha3.ts deleted file mode 100644 index 2bfbd6d7b..000000000 --- a/std/hash/sha3.ts +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -export { Sha3_224, Sha3_256, Sha3_384, Sha3_512 } from "./_sha3/sha3.ts"; -export { Keccak224, Keccak256, Keccak384, Keccak512 } from "./_sha3/keccak.ts"; -export { Shake128, Shake256 } from "./_sha3/shake.ts"; diff --git a/std/hash/sha3_test.ts b/std/hash/sha3_test.ts deleted file mode 100644 index 5ceea075d..000000000 --- a/std/hash/sha3_test.ts +++ /dev/null @@ -1,585 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -import { assertEquals, assertThrows } from "../testing/asserts.ts"; -import { - Keccak224, - Keccak256, - Keccak384, - Keccak512, - // deno-lint-ignore camelcase - Sha3_224, - // deno-lint-ignore camelcase - Sha3_256, - // deno-lint-ignore camelcase - Sha3_384, - // deno-lint-ignore camelcase - Sha3_512, - Shake128, - Shake256, -} from "./sha3.ts"; -import * as hex from "../encoding/hex.ts"; - -const millionAs = "a".repeat(1000000); - -// deno-lint-ignore camelcase -const testSetSha3_224 = [ - ["", "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7"], - ["abc", "e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf"], - [ - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - "8a24108b154ada21c9fd5574494479ba5c7e7ab76ef264ead0fcce33", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "f9019111996dcf160e284e320fd6d8825cabcd41a5ffdc4c5e9d64b6", - ], - [millionAs, "d69335b93325192e516a912e6d19a15cb51c6ed5c15243e7a7fd653c"], -]; - -// deno-lint-ignore camelcase -const testSetSha3_256 = [ - ["", "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"], - ["abc", "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532"], - [ - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - "41c0dba2a9d6240849100376a8235e2c82e1b9998a999e21db32dd97496d3376", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "3fc5559f14db8e453a0a3091edbd2bc25e11528d81c66fa570a4efdcc2695ee1", - ], - [ - millionAs, - "5c8875ae474a3634ba4fd55ec85bffd661f32aca75c6d699d0cdcb6c115891c1", - ], -]; - -// deno-lint-ignore camelcase -const testSetSha3_384 = [ - [ - "", - "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004", - ], - [ - "abc", - "ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "3a4f3b6284e571238884e95655e8c8a60e068e4059a9734abc08823a900d161592860243f00619ae699a29092ed91a16", - ], - [ - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - "991c665755eb3a4b6bbdfb75c78a492e8c56a22c5c4d7e429bfdbc32b9d4ad5aa04a1f076e62fea19eef51acd0657c22", - ], - [ - millionAs, - "eee9e24d78c1855337983451df97c8ad9eedf256c6334f8e948d252d5e0e76847aa0774ddb90a842190d2c558b4b8340", - ], -]; - -// deno-lint-ignore camelcase -const testSetSha3_512 = [ - [ - "", - "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26", - ], - [ - "abc", - "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0", - ], - [ - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - "04a371e84ecfb5b8b77cb48610fca8182dd457ce6f326a0fd3d7ec2f1e91636dee691fbe0c985302ba1b0d8dc78c086346b533b49c030d99a27daf1139d6e75e", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "a8ae722a78e10cbbc413886c02eb5b369a03f6560084aff566bd597bb7ad8c1ccd86e81296852359bf2faddb5153c0a7445722987875e74287adac21adebe952", - ], - [ - millionAs, - "3c3a876da14034ab60627c077bb98f7e120a2a5370212dffb3385a18d4f38859ed311d0a9d5141ce9cc5c66ee689b266a8aa18ace8282a0e0db596c90b0a7b87", - ], -]; - -const testSetKeccak224 = [ - ["", "f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd"], - ["abc", "c30411768506ebe1c2871b1ee2e87d38df342317300a9b97a95ec6a8"], - [ - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - "e51faa2b4655150b931ee8d700dc202f763ca5f962c529eae55012b6", - ], - [millionAs, "19f9167be2a04c43abd0ed554788101b9c339031acc8e1468531303f"], -]; - -const testSetKeccak256 = [ - ["", "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"], - ["abc", "4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45"], - [ - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - "45d3b367a6904e6e8d502ee04999a7c27647f91fa845d456525fd352ae3d7371", - ], - [ - millionAs, - "fadae6b49f129bbb812be8407b7b2894f34aecf6dbd1f9b0f0c7e9853098fc96", - ], -]; - -const testSetKeccak384 = [ - [ - "", - "2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff", - ], - [ - "abc", - "f7df1165f033337be098e7d288ad6a2f74409d7a60b49c36642218de161b1f99f8c681e4afaf31a34db29fb763e3c28e", - ], - [ - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - "b41e8896428f1bcbb51e17abd6acc98052a3502e0d5bf7fa1af949b4d3c855e7c4dc2c390326b3f3e74c7b1e2b9a3657", - ], - [ - millionAs, - "0c8324e1ebc182822c5e2a086cac07c2fe00e3bce61d01ba8ad6b71780e2dec5fb89e5ae90cb593e57bc6258fdd94e17", - ], -]; - -const testSetKeccak512 = [ - [ - "", - "0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e", - ], - [ - "abc", - "18587dc2ea106b9a1563e32b3312421ca164c7f1f07bc922a9c83d77cea3a1e5d0c69910739025372dc14ac9642629379540c17e2a65b19d77aa511a9d00bb96", - ], - [ - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - "6aa6d3669597df6d5a007b00d09c20795b5c4218234e1698a944757a488ecdc09965435d97ca32c3cfed7201ff30e070cd947f1fc12b9d9214c467d342bcba5d", - ], - [ - millionAs, - "5cf53f2e556be5a624425ede23d0e8b2c7814b4ba0e4e09cbbf3c2fac7056f61e048fc341262875ebc58a5183fea651447124370c1ebf4d6c89bc9a7731063bb", - ], -]; - -const testSetShake128 = [ - ["", "7f9c2ba4e88f827d616045507605853e"], - ["abc", "5881092dd818bf5cf8a3ddb793fbcba7"], - [ - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - "1a96182b50fb8c7e74e0a707788f55e9", - ], - [millionAs, "9d222c79c4ff9d092cf6ca86143aa411"], -]; - -// deno-lint-ignore camelcase -const testSetShake128_224 = [ - ["", "7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eac"], - ["abc", "5881092dd818bf5cf8a3ddb793fbcba74097d5c526a6d35f97b83351"], - [ - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - "1a96182b50fb8c7e74e0a707788f55e98209b8d91fade8f32f8dd5cf", - ], - [millionAs, "9d222c79c4ff9d092cf6ca86143aa411e369973808ef97093255826c"], -]; - -// deno-lint-ignore camelcase -const testSetShake128_2048 = [ - [ - "", - "7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef263cb1eea988004b93103cfb0aeefd2a686e01fa4a58e8a3639ca8a1e3f9ae57e235b8cc873c23dc62b8d260169afa2f75ab916a58d974918835d25e6a435085b2badfd6dfaac359a5efbb7bcc4b59d538df9a04302e10c8bc1cbf1a0b3a5120ea17cda7cfad765f5623474d368ccca8af0007cd9f5e4c849f167a580b14aabdefaee7eef47cb0fca9767be1fda69419dfb927e9df07348b196691abaeb580b32def58538b8d23f87732ea63b02b4fa0f4873360e2841928cd60dd4cee8cc0d4c922a96188d032675c8ac850933c7aff1533b94c834adbb69c6115bad4692d8619", - ], - [ - "abc", - "5881092dd818bf5cf8a3ddb793fbcba74097d5c526a6d35f97b83351940f2cc844c50af32acd3f2cdd066568706f509bc1bdde58295dae3f891a9a0fca5783789a41f8611214ce612394df286a62d1a2252aa94db9c538956c717dc2bed4f232a0294c857c730aa16067ac1062f1201fb0d377cfb9cde4c63599b27f3462bba4a0ed296c801f9ff7f57302bb3076ee145f97a32ae68e76ab66c48d51675bd49acc29082f5647584e6aa01b3f5af057805f973ff8ecb8b226ac32ada6f01c1fcd4818cb006aa5b4cdb3611eb1e533c8964cacfdf31012cd3fb744d02225b988b475375faad996eb1b9176ecb0f8b2871723d6dbb804e23357e50732f5cfc904b1", - ], - [ - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - "1a96182b50fb8c7e74e0a707788f55e98209b8d91fade8f32f8dd5cff7bf21f54ee5f19550825a6e070030519e944263ac1c6765287065621f9fcb3201723e3223b63a46c2938aa953ba8401d0ea77b8d26490775566407b95673c0f4cc1ce9fd966148d7efdff26bbf9f48a21c6da35bfaa545654f70ae586ff10131420771483ec92edab408c767bf4c5b4fffaa80c8ca214d84c4dc700d0c50630b2ffc3793ea4d87258b4c9548c5485a5ca666ef73fbd816d418aea6395b503addd9b150f9e0663325f01e5518b71ffa1244ea284cebe0cea2f774d7b3a437dca3282e324777e19624bf2be3cd355c1bfbddb323a33f11efafb2448293501dc0454c6b72f", - ], - [ - millionAs, - "9d222c79c4ff9d092cf6ca86143aa411e369973808ef97093255826c5572ef58424c4b5c28475ffdcf981663867fec6321c1262e387bccf8ca676884c4a9d0c13bfa6869763d5ae4bbc9b3ccd09d1ca5ea7446538d69b3fb98c72b59a2b4817db5eadd9011f90fa71091931f8134f4f00b562e2fe105937270361c1909862ad45046e3932f5dd311ec72fec5f8fb8f60b45a3bee3f85bbf7fcedc6a555677648e0654b381941a86bd3e512657b0d57a7991fc4543f89d8290492222ce4a33e17602b3b99c009f7655f87535cdaa3716f58c47b8a157ad195f02809f27500b9254979311c6bb415968cd10431169a27d5a8d61e13a6b8b77af1f8b6dd2eefdea0", - ], -]; - -const testSetShake256 = [ - ["", "46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f"], - ["abc", "483366601360a8771c6863080cc4114d8db44530f8f1e1ee4f94ea37e78b5739"], - [ - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - "4d8c2dd2435a0128eefbb8c36f6f87133a7911e18d979ee1ae6be5d4fd2e3329", - ], - [ - millionAs, - "3578a7a4ca9137569cdf76ed617d31bb994fca9c1bbf8b184013de8234dfd13a", - ], -]; - -// deno-lint-ignore camelcase -const testSetShake256_128 = [ - ["", "46b9dd2b0ba88d13233b3feb743eeb24"], - ["abc", "483366601360a8771c6863080cc4114d"], - [ - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - "4d8c2dd2435a0128eefbb8c36f6f8713", - ], - [millionAs, "3578a7a4ca9137569cdf76ed617d31bb"], -]; - -// deno-lint-ignore camelcase -const testSetShake256_384 = [ - [ - "", - "46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762fd75dc4ddd8c0f200cb05019d67b592f6", - ], - [ - "abc", - "483366601360a8771c6863080cc4114d8db44530f8f1e1ee4f94ea37e78b5739d5a15bef186a5386c75744c0527e1faa", - ], - [ - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - "4d8c2dd2435a0128eefbb8c36f6f87133a7911e18d979ee1ae6be5d4fd2e332940d8688a4e6a59aa8060f1f9bc996c05", - ], - [ - millionAs, - "3578a7a4ca9137569cdf76ed617d31bb994fca9c1bbf8b184013de8234dfd13a3fd124d4df76c0a539ee7dd2f6e1ec34", - ], -]; - -// deno-lint-ignore camelcase -const testSetShake256_512 = [ - [ - "", - "46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762fd75dc4ddd8c0f200cb05019d67b592f6fc821c49479ab48640292eacb3b7c4be", - ], - [ - "abc", - "483366601360a8771c6863080cc4114d8db44530f8f1e1ee4f94ea37e78b5739d5a15bef186a5386c75744c0527e1faa9f8726e462a12a4feb06bd8801e751e4", - ], - [ - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - "4d8c2dd2435a0128eefbb8c36f6f87133a7911e18d979ee1ae6be5d4fd2e332940d8688a4e6a59aa8060f1f9bc996c05aca3c696a8b66279dc672c740bb224ec", - ], - [ - millionAs, - "3578a7a4ca9137569cdf76ed617d31bb994fca9c1bbf8b184013de8234dfd13a3fd124d4df76c0a539ee7dd2f6e1ec346124c815d9410e145eb561bcd97b18ab", - ], -]; - -function s2b(data: string): Uint8Array { - return new TextEncoder().encode(data); -} - -Deno.test("[hash/sha3] testSha3-224Raw", () => { - const sha3sum = (data: ArrayBuffer): ArrayBuffer => { - const sha3 = new Sha3_224(); - return sha3.update(data).digest(); - }; - - for (const [input, output] of testSetSha3_224) { - const rawOutput = hex.decodeString(output); - assertEquals(sha3sum(s2b(input)), rawOutput); - } -}); - -Deno.test("[hash/sha3] testSha3-224String", () => { - const sha3sum = (data: string): string => { - const sha3 = new Sha3_224(); - return sha3.update(data).toString(); - }; - - for (const [input, output] of testSetSha3_224) { - assertEquals(sha3sum(input), output); - } -}); - -Deno.test("[hash/sha3] testSha3-256Raw", () => { - const sha3sum = (data: ArrayBuffer): ArrayBuffer => { - const sha3 = new Sha3_256(); - return sha3.update(data).digest(); - }; - - for (const [input, output] of testSetSha3_256) { - const rawOutput = hex.decodeString(output); - assertEquals(sha3sum(s2b(input)), rawOutput); - } -}); - -Deno.test("[hash/sha3] testSha3-256String", () => { - const sha3sum = (data: string): string => { - const sha3 = new Sha3_256(); - return sha3.update(data).toString(); - }; - - for (const [input, output] of testSetSha3_256) { - assertEquals(sha3sum(input), output); - } -}); - -Deno.test("[hash/sha3] testSha3-384Raw", () => { - const sha3sum = (data: ArrayBuffer): ArrayBuffer => { - const sha3 = new Sha3_384(); - return sha3.update(data).digest(); - }; - - for (const [input, output] of testSetSha3_384) { - const rawOutput = hex.decodeString(output); - assertEquals(sha3sum(s2b(input)), rawOutput); - } -}); - -Deno.test("[hash/sha3] testSha3-384String", () => { - const sha3sum = (data: string): string => { - const sha3 = new Sha3_384(); - return sha3.update(data).toString(); - }; - - for (const [input, output] of testSetSha3_384) { - assertEquals(sha3sum(input), output); - } -}); - -Deno.test("[hash/sha3] testSha3-512Raw", () => { - const sha3sum = (data: ArrayBuffer): ArrayBuffer => { - const sha3 = new Sha3_512(); - return sha3.update(data).digest(); - }; - - for (const [input, output] of testSetSha3_512) { - const rawOutput = hex.decodeString(output); - assertEquals(sha3sum(s2b(input)), rawOutput); - } -}); - -Deno.test("[hash/sha3] testSha3-512String", () => { - const sha3sum = (data: string): string => { - const sha3 = new Sha3_512(); - return sha3.update(data).toString(); - }; - - for (const [input, output] of testSetSha3_512) { - assertEquals(sha3sum(input), output); - } -}); - -Deno.test("[hash/sha3] testKeccak-224Raw", () => { - const keccakSum = (data: ArrayBuffer): ArrayBuffer => { - const keccak = new Keccak224(); - return keccak.update(data).digest(); - }; - - for (const [input, output] of testSetKeccak224) { - const rawOutput = hex.decodeString(output); - assertEquals(keccakSum(s2b(input)), rawOutput); - } -}); - -Deno.test("[hash/sha3] testKeccak-224String", () => { - const keccakSum = (data: string): string => { - const keccak = new Keccak224(); - return keccak.update(data).toString(); - }; - - for (const [input, output] of testSetKeccak224) { - assertEquals(keccakSum(input), output); - } -}); - -Deno.test("[hash/sha3] testKeccak-256Raw", () => { - const keccakSum = (data: ArrayBuffer): ArrayBuffer => { - const keccak = new Keccak256(); - return keccak.update(data).digest(); - }; - - for (const [input, output] of testSetKeccak256) { - const rawOutput = hex.decodeString(output); - assertEquals(keccakSum(s2b(input)), rawOutput); - } -}); - -Deno.test("[hash/sha3] testKeccak-256String", () => { - const keccakSum = (data: string): string => { - const keccak = new Keccak256(); - return keccak.update(data).toString(); - }; - - for (const [input, output] of testSetKeccak256) { - assertEquals(keccakSum(input), output); - } -}); - -Deno.test("[hash/sha3] testKeccak-384Raw", () => { - const keccakSum = (data: ArrayBuffer): ArrayBuffer => { - const keccak = new Keccak384(); - return keccak.update(data).digest(); - }; - - for (const [input, output] of testSetKeccak384) { - const rawOutput = hex.decodeString(output); - assertEquals(keccakSum(s2b(input)), rawOutput); - } -}); - -Deno.test("[hash/sha3] testKeccak-384String", () => { - const keccakSum = (data: string): string => { - const keccak = new Keccak384(); - return keccak.update(data).toString(); - }; - - for (const [input, output] of testSetKeccak384) { - assertEquals(keccakSum(input), output); - } -}); - -Deno.test("[hash/sha3] testKeccak-512Raw", () => { - const keccakSum = (data: ArrayBuffer): ArrayBuffer => { - const keccak = new Keccak512(); - return keccak.update(data).digest(); - }; - - for (const [input, output] of testSetKeccak512) { - const rawOutput = hex.decodeString(output); - assertEquals(keccakSum(s2b(input)), rawOutput); - } -}); - -Deno.test("[hash/sha3] testKeccak-512String", () => { - const keccakSum = (data: string): string => { - const keccak = new Keccak512(); - return keccak.update(data).toString(); - }; - - for (const [input, output] of testSetKeccak512) { - assertEquals(keccakSum(input), output); - } -}); - -Deno.test("[hash/sha3] testSHAKE-128Raw", () => { - const shakeSum = (data: ArrayBuffer): ArrayBuffer => { - const shake = new Shake128(128); - return shake.update(data).digest(); - }; - - for (const [input, output] of testSetShake128) { - const rawOutput = hex.decodeString(output); - assertEquals(shakeSum(s2b(input)), rawOutput); - } -}); - -Deno.test("[hash/sha3] testSHAKE-128String", () => { - const shakeSum = (data: string): string => { - const shake = new Shake128(128); - return shake.update(data).toString(); - }; - - for (const [input, output] of testSetShake128) { - assertEquals(shakeSum(input), output); - } -}); - -Deno.test("[hash/sha3] testSHAKE-128-224Raw", () => { - const shakeSum = (data: ArrayBuffer): ArrayBuffer => { - const shake = new Shake128(224); - return shake.update(data).digest(); - }; - - for (const [input, output] of testSetShake128_224) { - const rawOutput = hex.decodeString(output); - assertEquals(shakeSum(s2b(input)), rawOutput); - } -}); - -Deno.test("[hash/sha3] testSHAKE-128-224String", () => { - const shakeSum = (data: string): string => { - const shake = new Shake128(224); - return shake.update(data).toString(); - }; - - for (const [input, output] of testSetShake128_224) { - assertEquals(shakeSum(input), output); - } -}); - -Deno.test("[hash/sha3] testSHAKE-128-2048", () => { - const shakeSum = (data: string): string => { - const shake = new Shake128(2048); - return shake.update(data).toString(); - }; - - for (const [input, output] of testSetShake128_2048) { - assertEquals(shakeSum(input), output); - } -}); - -Deno.test("[hash/sha3] testSHAKE-256", () => { - const shakeSum = (data: string): string => { - const shake = new Shake256(256); - return shake.update(data).toString(); - }; - - for (const [input, output] of testSetShake256) { - assertEquals(shakeSum(input), output); - } -}); - -Deno.test("[hash/sha3] testSHAKE-256-128", () => { - const shakeSum = (data: string): string => { - const shake = new Shake256(128); - return shake.update(data).toString(); - }; - - for (const [input, output] of testSetShake256_128) { - assertEquals(shakeSum(input), output); - } -}); - -Deno.test("[hash/sha3] testSHAKE-256-384", () => { - const shakeSum = (data: string): string => { - const shake = new Shake256(384); - return shake.update(data).toString(); - }; - - for (const [input, output] of testSetShake256_384) { - assertEquals(shakeSum(input), output); - } -}); - -Deno.test("[hash/sha3] testSHAKE-256-512", () => { - const shakeSum = (data: string): string => { - const shake = new Shake256(512); - return shake.update(data).toString(); - }; - - for (const [input, output] of testSetShake256_512) { - assertEquals(shakeSum(input), output); - } -}); - -Deno.test("[hash/sha3] testSha3-256Chain", () => { - const sha3 = new Sha3_256(); - const output = sha3 - .update(s2b("a")) - .update(s2b("b")) - .update(s2b("c")) - .toString(); - - assertEquals( - output, - "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532", - ); -}); - -Deno.test("[hash/sha3] testSha3UpdateFinalized", () => { - assertThrows( - () => { - const sha3 = new Sha3_256(); - const hash = sha3.update(s2b("a")).digest(); - const hash2 = sha3.update(s2b("a")).digest(); - assertEquals(hash, hash2); - }, - Error, - "sha3: cannot update already finalized hash", - ); -}); diff --git a/std/hash/sha512.ts b/std/hash/sha512.ts deleted file mode 100644 index 98b0fec31..000000000 --- a/std/hash/sha512.ts +++ /dev/null @@ -1,791 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -/* - * [js-sha512]{@link https://github.com/emn178/js-sha512} - * - * @version 0.8.0 - * @author Chen, Yi-Cyuan [emn178@gmail.com] - * @copyright Chen, Yi-Cyuan 2014-2018 - * @license MIT - */ - -export type Message = string | number[] | ArrayBuffer; - -// deno-fmt-ignore -const HEX_CHARS = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"] as const; -const EXTRA = [-2147483648, 8388608, 32768, 128] as const; -const SHIFT = [24, 16, 8, 0] as const; -// deno-fmt-ignore -const K = [ - 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd, 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc, 0x3956c25b, - 0xf348b538, 0x59f111f1, 0xb605d019, 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118, 0xd807aa98, 0xa3030242, - 0x12835b01, 0x45706fbe, 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2, 0x72be5d74, 0xf27b896f, 0x80deb1fe, - 0x3b1696b1, 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694, 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3, - 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65, 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483, 0x5cb0a9dc, - 0xbd41fbd4, 0x76f988da, 0x831153b5, 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210, 0xb00327c8, 0x98fb213f, - 0xbf597fc7, 0xbeef0ee4, 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725, 0x06ca6351, 0xe003826f, 0x14292967, - 0x0a0e6e70, 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926, 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df, - 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8, 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b, 0xa2bfe8a1, - 0x4cf10364, 0xa81a664b, 0xbc423001, 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30, 0xd192e819, 0xd6ef5218, - 0xd6990624, 0x5565a910, 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8, 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, - 0x5141ab53, 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8, 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb, - 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3, 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60, 0x84c87814, - 0xa1f0ab72, 0x8cc70208, 0x1a6439ec, 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9, 0xbef9a3f7, 0xb2c67915, - 0xc67178f2, 0xe372532b, 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207, 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, - 0xee6ed178, 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6, 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b, - 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493, 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c, 0x4cc5d4be, - 0xcb3e42b6, 0x597f299c, 0xfc657e2a, 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817 -] as const; - -const blocks: number[] = []; - -// deno-fmt-ignore -export class Sha512 { - #blocks!: number[]; - #block!: number; - #bits!: number; - #start!: number; - #bytes!: number; - #hBytes!: number; - #lastByteIndex = 0; - #finalized!: boolean; - #hashed!: boolean; - #h0h!: number; - #h0l!: number; - #h1h!: number; - #h1l!: number; - #h2h!: number; - #h2l!: number; - #h3h!: number; - #h3l!: number; - #h4h!: number; - #h4l!: number; - #h5h!: number; - #h5l!: number; - #h6h!: number; - #h6l!: number; - #h7h!: number; - #h7l!: number; - - constructor(bits = 512, sharedMemory = false) { - this.init(bits, sharedMemory); - } - - protected init(bits: number, sharedMemory: boolean): void { - if (sharedMemory) { - blocks[0] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = - blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = blocks[16] = - blocks[17] = blocks[18] = blocks[19] = blocks[20] = blocks[21] = blocks[22] = blocks[23] = blocks[24] = - blocks[25] = blocks[26] = blocks[27] = blocks[28] = blocks[29] = blocks[30] = blocks[31] = blocks[32] = 0; - this.#blocks = blocks; - } else { - this.#blocks = - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - } - if (bits === 224) { - this.#h0h = 0x8c3d37c8; - this.#h0l = 0x19544da2; - this.#h1h = 0x73e19966; - this.#h1l = 0x89dcd4d6; - this.#h2h = 0x1dfab7ae; - this.#h2l = 0x32ff9c82; - this.#h3h = 0x679dd514; - this.#h3l = 0x582f9fcf; - this.#h4h = 0x0f6d2b69; - this.#h4l = 0x7bd44da8; - this.#h5h = 0x77e36f73; - this.#h5l = 0x04c48942; - this.#h6h = 0x3f9d85a8; - this.#h6l = 0x6a1d36c8; - this.#h7h = 0x1112e6ad; - this.#h7l = 0x91d692a1; - } else if (bits === 256) { - this.#h0h = 0x22312194; - this.#h0l = 0xfc2bf72c; - this.#h1h = 0x9f555fa3; - this.#h1l = 0xc84c64c2; - this.#h2h = 0x2393b86b; - this.#h2l = 0x6f53b151; - this.#h3h = 0x96387719; - this.#h3l = 0x5940eabd; - this.#h4h = 0x96283ee2; - this.#h4l = 0xa88effe3; - this.#h5h = 0xbe5e1e25; - this.#h5l = 0x53863992; - this.#h6h = 0x2b0199fc; - this.#h6l = 0x2c85b8aa; - this.#h7h = 0x0eb72ddc; - this.#h7l = 0x81c52ca2; - } else if (bits === 384) { - this.#h0h = 0xcbbb9d5d; - this.#h0l = 0xc1059ed8; - this.#h1h = 0x629a292a; - this.#h1l = 0x367cd507; - this.#h2h = 0x9159015a; - this.#h2l = 0x3070dd17; - this.#h3h = 0x152fecd8; - this.#h3l = 0xf70e5939; - this.#h4h = 0x67332667; - this.#h4l = 0xffc00b31; - this.#h5h = 0x8eb44a87; - this.#h5l = 0x68581511; - this.#h6h = 0xdb0c2e0d; - this.#h6l = 0x64f98fa7; - this.#h7h = 0x47b5481d; - this.#h7l = 0xbefa4fa4; - } else { // 512 - this.#h0h = 0x6a09e667; - this.#h0l = 0xf3bcc908; - this.#h1h = 0xbb67ae85; - this.#h1l = 0x84caa73b; - this.#h2h = 0x3c6ef372; - this.#h2l = 0xfe94f82b; - this.#h3h = 0xa54ff53a; - this.#h3l = 0x5f1d36f1; - this.#h4h = 0x510e527f; - this.#h4l = 0xade682d1; - this.#h5h = 0x9b05688c; - this.#h5l = 0x2b3e6c1f; - this.#h6h = 0x1f83d9ab; - this.#h6l = 0xfb41bd6b; - this.#h7h = 0x5be0cd19; - this.#h7l = 0x137e2179; - } - this.#bits = bits; - this.#block = this.#start = this.#bytes = this.#hBytes = 0; - this.#finalized = this.#hashed = false; - } - - update(message: Message): this { - if (this.#finalized) { - return this; - } - let msg: string | number[] | Uint8Array; - if (message instanceof ArrayBuffer) { - msg = new Uint8Array(message); - } else { - msg = message; - } - const length = msg.length; - const blocks = this.#blocks; - let index = 0; - while (index < length) { - let i: number; - if (this.#hashed) { - this.#hashed = false; - blocks[0] = this.#block; - blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = - blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = blocks[16] = - blocks[17] = blocks[18] = blocks[19] = blocks[20] = blocks[21] = blocks[22] = blocks[23] = blocks[24] = - blocks[25] = blocks[26] = blocks[27] = blocks[28] = blocks[29] = blocks[30] = blocks[31] = blocks[32] = 0; - } - if (typeof msg !== "string") { - for (i = this.#start; index < length && i < 128; ++index) { - blocks[i >> 2] |= msg[index] << SHIFT[i++ & 3]; - } - } else { - for (i = this.#start; index < length && i < 128; ++index) { - let code = msg.charCodeAt(index); - if (code < 0x80) { - blocks[i >> 2] |= code << SHIFT[i++ & 3]; - } else if (code < 0x800) { - blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } else if (code < 0xd800 || code >= 0xe000) { - blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } else { - code = 0x10000 + (((code & 0x3ff) << 10) | (msg.charCodeAt(++index) & 0x3ff)); - blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } - } - } - this.#lastByteIndex = i; - this.#bytes += i - this.#start; - if (i >= 128) { - this.#block = blocks[32]; - this.#start = i - 128; - this.hash(); - this.#hashed = true; - } else { - this.#start = i; - } - } - if (this.#bytes > 4294967295) { - this.#hBytes += (this.#bytes / 4294967296) << 0; - this.#bytes = this.#bytes % 4294967296; - } - return this; - } - - protected finalize(): void { - if (this.#finalized) { - return; - } - this.#finalized = true; - const blocks = this.#blocks; - const i = this.#lastByteIndex; - blocks[32] = this.#block; - blocks[i >> 2] |= EXTRA[i & 3]; - this.#block = blocks[32]; - if (i >= 112) { - if (!this.#hashed) { - this.hash(); - } - blocks[0] = this.#block; - blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = - blocks[9] =blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = blocks[16] = - blocks[17] = blocks[18] = blocks[19] = blocks[20] = blocks[21] = blocks[22] = blocks[23] = blocks[24] = - blocks[25] = blocks[26] = blocks[27] = blocks[28] = blocks[29] = blocks[30] = blocks[31] = blocks[32] = 0; - } - blocks[30] = (this.#hBytes << 3) | (this.#bytes >>> 29); - blocks[31] = this.#bytes << 3; - this.hash(); - } - - protected hash(): void { - const - h0h = this.#h0h, h0l = this.#h0l, h1h = this.#h1h, h1l = this.#h1l, h2h = this.#h2h, h2l = this.#h2l, - h3h = this.#h3h, h3l = this.#h3l, h4h = this.#h4h, h4l = this.#h4l, h5h = this.#h5h, h5l = this.#h5l, - h6h = this.#h6h, h6l = this.#h6l, h7h = this.#h7h, h7l = this.#h7l; - - let s0h, s0l, s1h, s1l, c1, c2, c3, c4, abh, abl, dah, dal, cdh, cdl, bch, bcl, majh, majl, - t1h, t1l, t2h, t2l, chh, chl: number; - - const blocks = this.#blocks; - - for (let j = 32; j < 160; j += 2) { - t1h = blocks[j - 30]; - t1l = blocks[j - 29]; - s0h = ((t1h >>> 1) | (t1l << 31)) ^ ((t1h >>> 8) | (t1l << 24)) ^ (t1h >>> 7); - s0l = ((t1l >>> 1) | (t1h << 31)) ^ ((t1l >>> 8) | (t1h << 24)) ^ ((t1l >>> 7) | (t1h << 25)); - - t1h = blocks[j - 4]; - t1l = blocks[j - 3]; - s1h = ((t1h >>> 19) | (t1l << 13)) ^ ((t1l >>> 29) | (t1h << 3)) ^ (t1h >>> 6); - s1l = ((t1l >>> 19) | (t1h << 13)) ^ ((t1h >>> 29) | (t1l << 3)) ^ ((t1l >>> 6) | (t1h << 26)); - - t1h = blocks[j - 32]; - t1l = blocks[j - 31]; - t2h = blocks[j - 14]; - t2l = blocks[j - 13]; - - c1 = (t2l & 0xffff) + (t1l & 0xffff) + (s0l & 0xffff) + (s1l & 0xffff); - c2 = (t2l >>> 16) + (t1l >>> 16) + (s0l >>> 16) + (s1l >>> 16) + (c1 >>> 16); - c3 = (t2h & 0xffff) + (t1h & 0xffff) + (s0h & 0xffff) + (s1h & 0xffff) + (c2 >>> 16); - c4 = (t2h >>> 16) + (t1h >>> 16) + (s0h >>> 16) + (s1h >>> 16) + (c3 >>> 16); - - blocks[j] = (c4 << 16) | (c3 & 0xffff); - blocks[j + 1] = (c2 << 16) | (c1 & 0xffff); - } - - let ah = h0h, al = h0l, bh = h1h, bl = h1l, ch = h2h, cl = h2l, dh = h3h, dl = h3l, eh = h4h, el = h4l, - fh = h5h, fl = h5l, gh = h6h, gl = h6l, hh = h7h, hl = h7l; - - bch = bh & ch; - bcl = bl & cl; - - for (let j = 0; j < 160; j += 8) { - s0h = ((ah >>> 28) | (al << 4)) ^ ((al >>> 2) | (ah << 30)) ^ ((al >>> 7) | (ah << 25)); - s0l = ((al >>> 28) | (ah << 4)) ^ ((ah >>> 2) | (al << 30)) ^ ((ah >>> 7) | (al << 25)); - - s1h = ((eh >>> 14) | (el << 18)) ^ ((eh >>> 18) | (el << 14)) ^ ((el >>> 9) | (eh << 23)); - s1l = ((el >>> 14) | (eh << 18)) ^ ((el >>> 18) | (eh << 14)) ^ ((eh >>> 9) | (el << 23)); - - abh = ah & bh; - abl = al & bl; - majh = abh ^ (ah & ch) ^ bch; - majl = abl ^ (al & cl) ^ bcl; - - chh = (eh & fh) ^ (~eh & gh); - chl = (el & fl) ^ (~el & gl); - - t1h = blocks[j]; - t1l = blocks[j + 1]; - t2h = K[j]; - t2l = K[j + 1]; - - c1 = (t2l & 0xffff) + (t1l & 0xffff) + (chl & 0xffff) + (s1l & 0xffff) + (hl & 0xffff); - c2 = (t2l >>> 16) + (t1l >>> 16) + (chl >>> 16) + (s1l >>> 16) + (hl >>> 16) + (c1 >>> 16); - c3 = (t2h & 0xffff) + (t1h & 0xffff) + (chh & 0xffff) + (s1h & 0xffff) + (hh & 0xffff) + (c2 >>> 16); - c4 = (t2h >>> 16) + (t1h >>> 16) + (chh >>> 16) + (s1h >>> 16) + (hh >>> 16) + (c3 >>> 16); - - t1h = (c4 << 16) | (c3 & 0xffff); - t1l = (c2 << 16) | (c1 & 0xffff); - - c1 = (majl & 0xffff) + (s0l & 0xffff); - c2 = (majl >>> 16) + (s0l >>> 16) + (c1 >>> 16); - c3 = (majh & 0xffff) + (s0h & 0xffff) + (c2 >>> 16); - c4 = (majh >>> 16) + (s0h >>> 16) + (c3 >>> 16); - - t2h = (c4 << 16) | (c3 & 0xffff); - t2l = (c2 << 16) | (c1 & 0xffff); - - c1 = (dl & 0xffff) + (t1l & 0xffff); - c2 = (dl >>> 16) + (t1l >>> 16) + (c1 >>> 16); - c3 = (dh & 0xffff) + (t1h & 0xffff) + (c2 >>> 16); - c4 = (dh >>> 16) + (t1h >>> 16) + (c3 >>> 16); - - hh = (c4 << 16) | (c3 & 0xffff); - hl = (c2 << 16) | (c1 & 0xffff); - - c1 = (t2l & 0xffff) + (t1l & 0xffff); - c2 = (t2l >>> 16) + (t1l >>> 16) + (c1 >>> 16); - c3 = (t2h & 0xffff) + (t1h & 0xffff) + (c2 >>> 16); - c4 = (t2h >>> 16) + (t1h >>> 16) + (c3 >>> 16); - - dh = (c4 << 16) | (c3 & 0xffff); - dl = (c2 << 16) | (c1 & 0xffff); - - s0h = ((dh >>> 28) | (dl << 4)) ^ ((dl >>> 2) | (dh << 30)) ^ ((dl >>> 7) | (dh << 25)); - s0l = ((dl >>> 28) | (dh << 4)) ^ ((dh >>> 2) | (dl << 30)) ^ ((dh >>> 7) | (dl << 25)); - - s1h = ((hh >>> 14) | (hl << 18)) ^ ((hh >>> 18) | (hl << 14)) ^ ((hl >>> 9) | (hh << 23)); - s1l = ((hl >>> 14) | (hh << 18)) ^ ((hl >>> 18) | (hh << 14)) ^ ((hh >>> 9) | (hl << 23)); - - dah = dh & ah; - dal = dl & al; - majh = dah ^ (dh & bh) ^ abh; - majl = dal ^ (dl & bl) ^ abl; - - chh = (hh & eh) ^ (~hh & fh); - chl = (hl & el) ^ (~hl & fl); - - t1h = blocks[j + 2]; - t1l = blocks[j + 3]; - t2h = K[j + 2]; - t2l = K[j + 3]; - - c1 = (t2l & 0xffff) + (t1l & 0xffff) + (chl & 0xffff) + (s1l & 0xffff) + (gl & 0xffff); - c2 = (t2l >>> 16) + (t1l >>> 16) + (chl >>> 16) + (s1l >>> 16) + (gl >>> 16) + (c1 >>> 16); - c3 = (t2h & 0xffff) + (t1h & 0xffff) + (chh & 0xffff) + (s1h & 0xffff) + (gh & 0xffff) + (c2 >>> 16); - c4 = (t2h >>> 16) + (t1h >>> 16) + (chh >>> 16) + (s1h >>> 16) + (gh >>> 16) + (c3 >>> 16); - - t1h = (c4 << 16) | (c3 & 0xffff); - t1l = (c2 << 16) | (c1 & 0xffff); - - c1 = (majl & 0xffff) + (s0l & 0xffff); - c2 = (majl >>> 16) + (s0l >>> 16) + (c1 >>> 16); - c3 = (majh & 0xffff) + (s0h & 0xffff) + (c2 >>> 16); - c4 = (majh >>> 16) + (s0h >>> 16) + (c3 >>> 16); - - t2h = (c4 << 16) | (c3 & 0xffff); - t2l = (c2 << 16) | (c1 & 0xffff); - - c1 = (cl & 0xffff) + (t1l & 0xffff); - c2 = (cl >>> 16) + (t1l >>> 16) + (c1 >>> 16); - c3 = (ch & 0xffff) + (t1h & 0xffff) + (c2 >>> 16); - c4 = (ch >>> 16) + (t1h >>> 16) + (c3 >>> 16); - - gh = (c4 << 16) | (c3 & 0xffff); - gl = (c2 << 16) | (c1 & 0xffff); - - c1 = (t2l & 0xffff) + (t1l & 0xffff); - c2 = (t2l >>> 16) + (t1l >>> 16) + (c1 >>> 16); - c3 = (t2h & 0xffff) + (t1h & 0xffff) + (c2 >>> 16); - c4 = (t2h >>> 16) + (t1h >>> 16) + (c3 >>> 16); - - ch = (c4 << 16) | (c3 & 0xffff); - cl = (c2 << 16) | (c1 & 0xffff); - - s0h = ((ch >>> 28) | (cl << 4)) ^ ((cl >>> 2) | (ch << 30)) ^ ((cl >>> 7) | (ch << 25)); - s0l = ((cl >>> 28) | (ch << 4)) ^ ((ch >>> 2) | (cl << 30)) ^ ((ch >>> 7) | (cl << 25)); - - s1h = ((gh >>> 14) | (gl << 18)) ^ ((gh >>> 18) | (gl << 14)) ^ ((gl >>> 9) | (gh << 23)); - s1l = ((gl >>> 14) | (gh << 18)) ^ ((gl >>> 18) | (gh << 14)) ^ ((gh >>> 9) | (gl << 23)); - - cdh = ch & dh; - cdl = cl & dl; - majh = cdh ^ (ch & ah) ^ dah; - majl = cdl ^ (cl & al) ^ dal; - - chh = (gh & hh) ^ (~gh & eh); - chl = (gl & hl) ^ (~gl & el); - - t1h = blocks[j + 4]; - t1l = blocks[j + 5]; - t2h = K[j + 4]; - t2l = K[j + 5]; - - c1 = (t2l & 0xffff) + (t1l & 0xffff) + (chl & 0xffff) + (s1l & 0xffff) + (fl & 0xffff); - c2 = (t2l >>> 16) + (t1l >>> 16) + (chl >>> 16) + (s1l >>> 16) + (fl >>> 16) + (c1 >>> 16); - c3 = (t2h & 0xffff) + (t1h & 0xffff) + (chh & 0xffff) + (s1h & 0xffff) + (fh & 0xffff) + (c2 >>> 16); - c4 = (t2h >>> 16) + (t1h >>> 16) + (chh >>> 16) + (s1h >>> 16) + (fh >>> 16) + (c3 >>> 16); - - t1h = (c4 << 16) | (c3 & 0xffff); - t1l = (c2 << 16) | (c1 & 0xffff); - - c1 = (majl & 0xffff) + (s0l & 0xffff); - c2 = (majl >>> 16) + (s0l >>> 16) + (c1 >>> 16); - c3 = (majh & 0xffff) + (s0h & 0xffff) + (c2 >>> 16); - c4 = (majh >>> 16) + (s0h >>> 16) + (c3 >>> 16); - - t2h = (c4 << 16) | (c3 & 0xffff); - t2l = (c2 << 16) | (c1 & 0xffff); - - c1 = (bl & 0xffff) + (t1l & 0xffff); - c2 = (bl >>> 16) + (t1l >>> 16) + (c1 >>> 16); - c3 = (bh & 0xffff) + (t1h & 0xffff) + (c2 >>> 16); - c4 = (bh >>> 16) + (t1h >>> 16) + (c3 >>> 16); - - fh = (c4 << 16) | (c3 & 0xffff); - fl = (c2 << 16) | (c1 & 0xffff); - - c1 = (t2l & 0xffff) + (t1l & 0xffff); - c2 = (t2l >>> 16) + (t1l >>> 16) + (c1 >>> 16); - c3 = (t2h & 0xffff) + (t1h & 0xffff) + (c2 >>> 16); - c4 = (t2h >>> 16) + (t1h >>> 16) + (c3 >>> 16); - - bh = (c4 << 16) | (c3 & 0xffff); - bl = (c2 << 16) | (c1 & 0xffff); - - s0h = ((bh >>> 28) | (bl << 4)) ^ ((bl >>> 2) | (bh << 30)) ^ ((bl >>> 7) | (bh << 25)); - s0l = ((bl >>> 28) | (bh << 4)) ^ ((bh >>> 2) | (bl << 30)) ^ ((bh >>> 7) | (bl << 25)); - - s1h = ((fh >>> 14) | (fl << 18)) ^ ((fh >>> 18) | (fl << 14)) ^ ((fl >>> 9) | (fh << 23)); - s1l = ((fl >>> 14) | (fh << 18)) ^ ((fl >>> 18) | (fh << 14)) ^ ((fh >>> 9) | (fl << 23)); - - bch = bh & ch; - bcl = bl & cl; - majh = bch ^ (bh & dh) ^ cdh; - majl = bcl ^ (bl & dl) ^ cdl; - - chh = (fh & gh) ^ (~fh & hh); - chl = (fl & gl) ^ (~fl & hl); - - t1h = blocks[j + 6]; - t1l = blocks[j + 7]; - t2h = K[j + 6]; - t2l = K[j + 7]; - - c1 = (t2l & 0xffff) + (t1l & 0xffff) + (chl & 0xffff) + (s1l & 0xffff) + (el & 0xffff); - c2 = (t2l >>> 16) + (t1l >>> 16) + (chl >>> 16) + (s1l >>> 16) + (el >>> 16) + (c1 >>> 16); - c3 = (t2h & 0xffff) + (t1h & 0xffff) + (chh & 0xffff) + (s1h & 0xffff) + (eh & 0xffff) + (c2 >>> 16); - c4 = (t2h >>> 16) + (t1h >>> 16) + (chh >>> 16) + (s1h >>> 16) + (eh >>> 16) + (c3 >>> 16); - - t1h = (c4 << 16) | (c3 & 0xffff); - t1l = (c2 << 16) | (c1 & 0xffff); - - c1 = (majl & 0xffff) + (s0l & 0xffff); - c2 = (majl >>> 16) + (s0l >>> 16) + (c1 >>> 16); - c3 = (majh & 0xffff) + (s0h & 0xffff) + (c2 >>> 16); - c4 = (majh >>> 16) + (s0h >>> 16) + (c3 >>> 16); - - t2h = (c4 << 16) | (c3 & 0xffff); - t2l = (c2 << 16) | (c1 & 0xffff); - - c1 = (al & 0xffff) + (t1l & 0xffff); - c2 = (al >>> 16) + (t1l >>> 16) + (c1 >>> 16); - c3 = (ah & 0xffff) + (t1h & 0xffff) + (c2 >>> 16); - c4 = (ah >>> 16) + (t1h >>> 16) + (c3 >>> 16); - - eh = (c4 << 16) | (c3 & 0xffff); - el = (c2 << 16) | (c1 & 0xffff); - - c1 = (t2l & 0xffff) + (t1l & 0xffff); - c2 = (t2l >>> 16) + (t1l >>> 16) + (c1 >>> 16); - c3 = (t2h & 0xffff) + (t1h & 0xffff) + (c2 >>> 16); - c4 = (t2h >>> 16) + (t1h >>> 16) + (c3 >>> 16); - - ah = (c4 << 16) | (c3 & 0xffff); - al = (c2 << 16) | (c1 & 0xffff); - } - - c1 = (h0l & 0xffff) + (al & 0xffff); - c2 = (h0l >>> 16) + (al >>> 16) + (c1 >>> 16); - c3 = (h0h & 0xffff) + (ah & 0xffff) + (c2 >>> 16); - c4 = (h0h >>> 16) + (ah >>> 16) + (c3 >>> 16); - - this.#h0h = (c4 << 16) | (c3 & 0xffff); - this.#h0l = (c2 << 16) | (c1 & 0xffff); - - c1 = (h1l & 0xffff) + (bl & 0xffff); - c2 = (h1l >>> 16) + (bl >>> 16) + (c1 >>> 16); - c3 = (h1h & 0xffff) + (bh & 0xffff) + (c2 >>> 16); - c4 = (h1h >>> 16) + (bh >>> 16) + (c3 >>> 16); - - this.#h1h = (c4 << 16) | (c3 & 0xffff); - this.#h1l = (c2 << 16) | (c1 & 0xffff); - - c1 = (h2l & 0xffff) + (cl & 0xffff); - c2 = (h2l >>> 16) + (cl >>> 16) + (c1 >>> 16); - c3 = (h2h & 0xffff) + (ch & 0xffff) + (c2 >>> 16); - c4 = (h2h >>> 16) + (ch >>> 16) + (c3 >>> 16); - - this.#h2h = (c4 << 16) | (c3 & 0xffff); - this.#h2l = (c2 << 16) | (c1 & 0xffff); - - c1 = (h3l & 0xffff) + (dl & 0xffff); - c2 = (h3l >>> 16) + (dl >>> 16) + (c1 >>> 16); - c3 = (h3h & 0xffff) + (dh & 0xffff) + (c2 >>> 16); - c4 = (h3h >>> 16) + (dh >>> 16) + (c3 >>> 16); - - this.#h3h = (c4 << 16) | (c3 & 0xffff); - this.#h3l = (c2 << 16) | (c1 & 0xffff); - - c1 = (h4l & 0xffff) + (el & 0xffff); - c2 = (h4l >>> 16) + (el >>> 16) + (c1 >>> 16); - c3 = (h4h & 0xffff) + (eh & 0xffff) + (c2 >>> 16); - c4 = (h4h >>> 16) + (eh >>> 16) + (c3 >>> 16); - - this.#h4h = (c4 << 16) | (c3 & 0xffff); - this.#h4l = (c2 << 16) | (c1 & 0xffff); - - c1 = (h5l & 0xffff) + (fl & 0xffff); - c2 = (h5l >>> 16) + (fl >>> 16) + (c1 >>> 16); - c3 = (h5h & 0xffff) + (fh & 0xffff) + (c2 >>> 16); - c4 = (h5h >>> 16) + (fh >>> 16) + (c3 >>> 16); - - this.#h5h = (c4 << 16) | (c3 & 0xffff); - this.#h5l = (c2 << 16) | (c1 & 0xffff); - - c1 = (h6l & 0xffff) + (gl & 0xffff); - c2 = (h6l >>> 16) + (gl >>> 16) + (c1 >>> 16); - c3 = (h6h & 0xffff) + (gh & 0xffff) + (c2 >>> 16); - c4 = (h6h >>> 16) + (gh >>> 16) + (c3 >>> 16); - - this.#h6h = (c4 << 16) | (c3 & 0xffff); - this.#h6l = (c2 << 16) | (c1 & 0xffff); - - c1 = (h7l & 0xffff) + (hl & 0xffff); - c2 = (h7l >>> 16) + (hl >>> 16) + (c1 >>> 16); - c3 = (h7h & 0xffff) + (hh & 0xffff) + (c2 >>> 16); - c4 = (h7h >>> 16) + (hh >>> 16) + (c3 >>> 16); - - this.#h7h = (c4 << 16) | (c3 & 0xffff); - this.#h7l = (c2 << 16) | (c1 & 0xffff); - } - - hex(): string { - this.finalize(); - const - h0h = this.#h0h, h0l = this.#h0l, h1h = this.#h1h, h1l = this.#h1l, h2h = this.#h2h, h2l = this.#h2l, - h3h = this.#h3h, h3l = this.#h3l, h4h = this.#h4h, h4l = this.#h4l, h5h = this.#h5h, h5l = this.#h5l, - h6h = this.#h6h, h6l = this.#h6l, h7h = this.#h7h, h7l = this.#h7l, bits = this.#bits; - let hex = - HEX_CHARS[(h0h >> 28) & 0x0f] + HEX_CHARS[(h0h >> 24) & 0x0f] + - HEX_CHARS[(h0h >> 20) & 0x0f] + HEX_CHARS[(h0h >> 16) & 0x0f] + - HEX_CHARS[(h0h >> 12) & 0x0f] + HEX_CHARS[(h0h >> 8) & 0x0f] + - HEX_CHARS[(h0h >> 4) & 0x0f] + HEX_CHARS[h0h & 0x0f] + - HEX_CHARS[(h0l >> 28) & 0x0f] + HEX_CHARS[(h0l >> 24) & 0x0f] + - HEX_CHARS[(h0l >> 20) & 0x0f] + HEX_CHARS[(h0l >> 16) & 0x0f] + - HEX_CHARS[(h0l >> 12) & 0x0f] + HEX_CHARS[(h0l >> 8) & 0x0f] + - HEX_CHARS[(h0l >> 4) & 0x0f] + HEX_CHARS[h0l & 0x0f] + - HEX_CHARS[(h1h >> 28) & 0x0f] + HEX_CHARS[(h1h >> 24) & 0x0f] + - HEX_CHARS[(h1h >> 20) & 0x0f] + HEX_CHARS[(h1h >> 16) & 0x0f] + - HEX_CHARS[(h1h >> 12) & 0x0f] + HEX_CHARS[(h1h >> 8) & 0x0f] + - HEX_CHARS[(h1h >> 4) & 0x0f] + HEX_CHARS[h1h & 0x0f] + - HEX_CHARS[(h1l >> 28) & 0x0f] + HEX_CHARS[(h1l >> 24) & 0x0f] + - HEX_CHARS[(h1l >> 20) & 0x0f] + HEX_CHARS[(h1l >> 16) & 0x0f] + - HEX_CHARS[(h1l >> 12) & 0x0f] + HEX_CHARS[(h1l >> 8) & 0x0f] + - HEX_CHARS[(h1l >> 4) & 0x0f] + HEX_CHARS[h1l & 0x0f] + - HEX_CHARS[(h2h >> 28) & 0x0f] + HEX_CHARS[(h2h >> 24) & 0x0f] + - HEX_CHARS[(h2h >> 20) & 0x0f] + HEX_CHARS[(h2h >> 16) & 0x0f] + - HEX_CHARS[(h2h >> 12) & 0x0f] + HEX_CHARS[(h2h >> 8) & 0x0f] + - HEX_CHARS[(h2h >> 4) & 0x0f] + HEX_CHARS[h2h & 0x0f] + - HEX_CHARS[(h2l >> 28) & 0x0f] + HEX_CHARS[(h2l >> 24) & 0x0f] + - HEX_CHARS[(h2l >> 20) & 0x0f] + HEX_CHARS[(h2l >> 16) & 0x0f] + - HEX_CHARS[(h2l >> 12) & 0x0f] + HEX_CHARS[(h2l >> 8) & 0x0f] + - HEX_CHARS[(h2l >> 4) & 0x0f] + HEX_CHARS[h2l & 0x0f] + - HEX_CHARS[(h3h >> 28) & 0x0f] + HEX_CHARS[(h3h >> 24) & 0x0f] + - HEX_CHARS[(h3h >> 20) & 0x0f] + HEX_CHARS[(h3h >> 16) & 0x0f] + - HEX_CHARS[(h3h >> 12) & 0x0f] + HEX_CHARS[(h3h >> 8) & 0x0f] + - HEX_CHARS[(h3h >> 4) & 0x0f] + HEX_CHARS[h3h & 0x0f]; - if (bits >= 256) { - hex += - HEX_CHARS[(h3l >> 28) & 0x0f] + HEX_CHARS[(h3l >> 24) & 0x0f] + - HEX_CHARS[(h3l >> 20) & 0x0f] + HEX_CHARS[(h3l >> 16) & 0x0f] + - HEX_CHARS[(h3l >> 12) & 0x0f] + HEX_CHARS[(h3l >> 8) & 0x0f] + - HEX_CHARS[(h3l >> 4) & 0x0f] + HEX_CHARS[h3l & 0x0f]; - } - if (bits >= 384) { - hex += - HEX_CHARS[(h4h >> 28) & 0x0f] + HEX_CHARS[(h4h >> 24) & 0x0f] + - HEX_CHARS[(h4h >> 20) & 0x0f] + HEX_CHARS[(h4h >> 16) & 0x0f] + - HEX_CHARS[(h4h >> 12) & 0x0f] + HEX_CHARS[(h4h >> 8) & 0x0f] + - HEX_CHARS[(h4h >> 4) & 0x0f] + HEX_CHARS[h4h & 0x0f] + - HEX_CHARS[(h4l >> 28) & 0x0f] + HEX_CHARS[(h4l >> 24) & 0x0f] + - HEX_CHARS[(h4l >> 20) & 0x0f] + HEX_CHARS[(h4l >> 16) & 0x0f] + - HEX_CHARS[(h4l >> 12) & 0x0f] + HEX_CHARS[(h4l >> 8) & 0x0f] + - HEX_CHARS[(h4l >> 4) & 0x0f] + HEX_CHARS[h4l & 0x0f] + - HEX_CHARS[(h5h >> 28) & 0x0f] + HEX_CHARS[(h5h >> 24) & 0x0f] + - HEX_CHARS[(h5h >> 20) & 0x0f] + HEX_CHARS[(h5h >> 16) & 0x0f] + - HEX_CHARS[(h5h >> 12) & 0x0f] + HEX_CHARS[(h5h >> 8) & 0x0f] + - HEX_CHARS[(h5h >> 4) & 0x0f] + HEX_CHARS[h5h & 0x0f] + - HEX_CHARS[(h5l >> 28) & 0x0f] + HEX_CHARS[(h5l >> 24) & 0x0f] + - HEX_CHARS[(h5l >> 20) & 0x0f] + HEX_CHARS[(h5l >> 16) & 0x0f] + - HEX_CHARS[(h5l >> 12) & 0x0f] + HEX_CHARS[(h5l >> 8) & 0x0f] + - HEX_CHARS[(h5l >> 4) & 0x0f] + HEX_CHARS[h5l & 0x0f]; - } - if (bits === 512) { - hex += - HEX_CHARS[(h6h >> 28) & 0x0f] + HEX_CHARS[(h6h >> 24) & 0x0f] + - HEX_CHARS[(h6h >> 20) & 0x0f] + HEX_CHARS[(h6h >> 16) & 0x0f] + - HEX_CHARS[(h6h >> 12) & 0x0f] + HEX_CHARS[(h6h >> 8) & 0x0f] + - HEX_CHARS[(h6h >> 4) & 0x0f] + HEX_CHARS[h6h & 0x0f] + - HEX_CHARS[(h6l >> 28) & 0x0f] + HEX_CHARS[(h6l >> 24) & 0x0f] + - HEX_CHARS[(h6l >> 20) & 0x0f] + HEX_CHARS[(h6l >> 16) & 0x0f] + - HEX_CHARS[(h6l >> 12) & 0x0f] + HEX_CHARS[(h6l >> 8) & 0x0f] + - HEX_CHARS[(h6l >> 4) & 0x0f] + HEX_CHARS[h6l & 0x0f] + - HEX_CHARS[(h7h >> 28) & 0x0f] + HEX_CHARS[(h7h >> 24) & 0x0f] + - HEX_CHARS[(h7h >> 20) & 0x0f] + HEX_CHARS[(h7h >> 16) & 0x0f] + - HEX_CHARS[(h7h >> 12) & 0x0f] + HEX_CHARS[(h7h >> 8) & 0x0f] + - HEX_CHARS[(h7h >> 4) & 0x0f] + HEX_CHARS[h7h & 0x0f] + - HEX_CHARS[(h7l >> 28) & 0x0f] + HEX_CHARS[(h7l >> 24) & 0x0f] + - HEX_CHARS[(h7l >> 20) & 0x0f] + HEX_CHARS[(h7l >> 16) & 0x0f] + - HEX_CHARS[(h7l >> 12) & 0x0f] + HEX_CHARS[(h7l >> 8) & 0x0f] + - HEX_CHARS[(h7l >> 4) & 0x0f] + HEX_CHARS[h7l & 0x0f]; - } - return hex; - } - - toString(): string { - return this.hex(); - } - - digest(): number[] { - this.finalize(); - const - h0h = this.#h0h, h0l = this.#h0l, h1h = this.#h1h, h1l = this.#h1l, h2h = this.#h2h, h2l = this.#h2l, - h3h = this.#h3h, h3l = this.#h3l, h4h = this.#h4h, h4l = this.#h4l, h5h = this.#h5h, h5l = this.#h5l, - h6h = this.#h6h, h6l = this.#h6l, h7h = this.#h7h, h7l = this.#h7l, bits = this.#bits; - const arr = [ - (h0h >> 24) & 0xff, (h0h >> 16) & 0xff, (h0h >> 8) & 0xff, h0h & 0xff, - (h0l >> 24) & 0xff, (h0l >> 16) & 0xff, (h0l >> 8) & 0xff, h0l & 0xff, - (h1h >> 24) & 0xff, (h1h >> 16) & 0xff, (h1h >> 8) & 0xff, h1h & 0xff, - (h1l >> 24) & 0xff, (h1l >> 16) & 0xff, (h1l >> 8) & 0xff, h1l & 0xff, - (h2h >> 24) & 0xff, (h2h >> 16) & 0xff, (h2h >> 8) & 0xff, h2h & 0xff, - (h2l >> 24) & 0xff, (h2l >> 16) & 0xff, (h2l >> 8) & 0xff, h2l & 0xff, - (h3h >> 24) & 0xff, (h3h >> 16) & 0xff, (h3h >> 8) & 0xff, h3h & 0xff - ]; - if (bits >= 256) { - arr.push((h3l >> 24) & 0xff, (h3l >> 16) & 0xff, (h3l >> 8) & 0xff, h3l & 0xff); - } - if (bits >= 384) { - arr.push( - (h4h >> 24) & 0xff, (h4h >> 16) & 0xff, (h4h >> 8) & 0xff, h4h & 0xff, - (h4l >> 24) & 0xff, (h4l >> 16) & 0xff, (h4l >> 8) & 0xff, h4l & 0xff, - (h5h >> 24) & 0xff, (h5h >> 16) & 0xff, (h5h >> 8) & 0xff, h5h & 0xff, - (h5l >> 24) & 0xff, (h5l >> 16) & 0xff, (h5l >> 8) & 0xff, h5l & 0xff - ); - } - if (bits === 512) { - arr.push( - (h6h >> 24) & 0xff, (h6h >> 16) & 0xff, (h6h >> 8) & 0xff, h6h & 0xff, - (h6l >> 24) & 0xff, (h6l >> 16) & 0xff, (h6l >> 8) & 0xff, h6l & 0xff, - (h7h >> 24) & 0xff, (h7h >> 16) & 0xff, (h7h >> 8) & 0xff, h7h & 0xff, - (h7l >> 24) & 0xff, (h7l >> 16) & 0xff, (h7l >> 8) & 0xff, h7l & 0xff - ); - } - return arr; - } - - array(): number[] { - return this.digest(); - } - - arrayBuffer(): ArrayBuffer { - this.finalize(); - const bits = this.#bits; - const buffer = new ArrayBuffer(bits / 8); - const dataView = new DataView(buffer); - dataView.setUint32(0, this.#h0h); - dataView.setUint32(4, this.#h0l); - dataView.setUint32(8, this.#h1h); - dataView.setUint32(12, this.#h1l); - dataView.setUint32(16, this.#h2h); - dataView.setUint32(20, this.#h2l); - dataView.setUint32(24, this.#h3h); - if (bits >= 256) { - dataView.setUint32(28, this.#h3l); - } - if (bits >= 384) { - dataView.setUint32(32, this.#h4h); - dataView.setUint32(36, this.#h4l); - dataView.setUint32(40, this.#h5h); - dataView.setUint32(44, this.#h5l); - } - if (bits === 512) { - dataView.setUint32(48, this.#h6h); - dataView.setUint32(52, this.#h6l); - dataView.setUint32(56, this.#h7h); - dataView.setUint32(60, this.#h7l); - } - return buffer; - } -} - -export class HmacSha512 extends Sha512 { - #inner: boolean; - #bits: number; - #oKeyPad: number[]; - #sharedMemory: boolean; - - constructor(secretKey: Message, bits = 512, sharedMemory = false) { - super(bits, sharedMemory); - - let key: number[] | Uint8Array; - - if (secretKey instanceof ArrayBuffer) { - key = new Uint8Array(secretKey); - } else if (typeof secretKey === "string") { - const bytes: number[] = []; - const length = secretKey.length; - let index = 0; - let code: number; - for (let i = 0; i < length; ++i) { - code = secretKey.charCodeAt(i); - if (code < 0x80) { - bytes[index++] = code; - } else if (code < 0x800) { - bytes[index++] = 0xc0 | (code >> 6); - bytes[index++] = 0x80 | (code & 0x3f); - } else if (code < 0xd800 || code >= 0xe000) { - bytes[index++] = 0xe0 | (code >> 12); - bytes[index++] = 0x80 | ((code >> 6) & 0x3f); - bytes[index++] = 0x80 | (code & 0x3f); - } else { - code = 0x10000 + - (((code & 0x3ff) << 10) | (secretKey.charCodeAt(++i) & 0x3ff)); - bytes[index++] = 0xf0 | (code >> 18); - bytes[index++] = 0x80 | ((code >> 12) & 0x3f); - bytes[index++] = 0x80 | ((code >> 6) & 0x3f); - bytes[index++] = 0x80 | (code & 0x3f); - } - } - key = bytes; - } else { - key = secretKey; - } - if (key.length > 128) { - key = new Sha512(bits, true).update(key).array(); - } - const oKeyPad: number[] = []; - const iKeyPad: number[] = []; - for (let i = 0; i < 128; ++i) { - const b = key[i] || 0; - oKeyPad[i] = 0x5c ^ b; - iKeyPad[i] = 0x36 ^ b; - } - this.update(iKeyPad); - this.#inner = true; - this.#bits = bits; - this.#oKeyPad = oKeyPad; - this.#sharedMemory = sharedMemory; - } - - protected finalize(): void { - super.finalize(); - if (this.#inner) { - this.#inner = false; - const innerHash = this.array(); - super.init(this.#bits, this.#sharedMemory); - this.update(this.#oKeyPad); - this.update(innerHash); - super.finalize(); - } - } -} diff --git a/std/hash/sha512_test.ts b/std/hash/sha512_test.ts deleted file mode 100644 index 97f199b4d..000000000 --- a/std/hash/sha512_test.ts +++ /dev/null @@ -1,400 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -import { HmacSha512, Message, Sha512 } from "./sha512.ts"; -import { assertEquals } from "../testing/asserts.ts"; -import { dirname, fromFileUrl, join, resolve } from "../path/mod.ts"; - -const moduleDir = dirname(fromFileUrl(import.meta.url)); -const testdataDir = resolve(moduleDir, "testdata"); - -/** Handy function to convert an array/array buffer to a string of hex values. */ -function toHexString(value: number[] | ArrayBuffer): string { - const array = new Uint8Array(value); - let hex = ""; - for (const v of array) { - const c = v.toString(16); - hex += c.length === 1 ? `0${c}` : c; - } - return hex; -} - -// deno-fmt-ignore -const fixtures: { - sha512bits224: Record<string, Record<string, Message>>, - sha512bits256: Record<string, Record<string, Message>>, - sha512: Record<string, Record<string, Message>>, - hmacSha512bits224: Record<string, Record<string, [Message, Message]>>, - hmacSha512bits256: Record<string, Record<string, [Message, Message]>>, - hmacSha512: Record<string, Record<string, [Message, Message]>> -} = { - sha512bits224: { - "ascii": { - "6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4": "", - "944cd2847fb54558d4775db0485a50003111c8e5daa63fe722c6aa37": "The quick brown fox jumps over the lazy dog", - "6d6a9279495ec4061769752e7ff9c68b6b0b3c5a281b7917ce0572de": "The quick brown fox jumps over the lazy dog." - }, - "ascii more than 64 bytes": { - "2e962464977b198ee758d615bbc92251ad2e3c0960068e279fd21d2f": "The MD5 message-digest algorithm is a widely used cryptographic hash function producing a 128-bit (16-byte) hash value, typically expressed in text format as a 32 digit hexadecimal number. MD5 has been utilized in a wide variety of cryptographic applications, and is also commonly used to verify data integrity." - }, - "UTF8": { - "0f46a0ae7f226517dd66ece0ce1efa29ffb7ced05ac4566fdcaed188": "中文", - "562f2e4ee7f7451d20dcc6a0ac1a1e1c4a75f09baaf1cf19af3e15f4": "aécio", - "0533318c52b3d4ad355c2a6c7e727ae3d2efa749db480ac33560b059": "𠜎" - }, - "UTF8 more than 64 bytes": { - "f67e191a5d4ee67a272ccaf6cf597f0c4d6a0c46bd631be7cadb0944": "訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一", - "009c3d1e3172d6df71344982eada855421592aea28acbf660ada7569": "訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一(又譯雜湊演算法、摘要演算法等),主流程式語言普遍已有MD5的實作。" - }, - "special length": { - "6fe6ce0f03b9cd09851e05ba5e3103df56d2a3dbb379fee437e1cdd3": "0123456780123456780123456780123456780123456780123456780", - "9e6994d879f14c242dea25ebc4d03ae6fc710f5eb60c3962b9dba797": "01234567801234567801234567801234567801234567801234567801", - "204ce3b2af187fe90494cb3e4517257c44917bb7ea6578264baa4fcf": "0123456780123456780123456780123456780123456780123456780123456780", - "69ce912fd1f87e02601d6153c02769ebd7c42b29dcb7963a1c3996da": "01234567801234567801234567801234567801234567801234567801234567801234567", - "bd98be1f148dddd8a98c6ba31628c354456b9754166738fe1aba1037": "012345678012345678012345678012345678012345678012345678012345678012345678" - }, - "Array": { - "6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4": [], - "6945cf025ed66055282665c546781e32c5a479b5e9b479e96b0c23fe": [211, 212], - "944cd2847fb54558d4775db0485a50003111c8e5daa63fe722c6aa37": [84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103], - "69ce912fd1f87e02601d6153c02769ebd7c42b29dcb7963a1c3996da": [48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55] - }, - "Uint8Array": { - "6945cf025ed66055282665c546781e32c5a479b5e9b479e96b0c23fe": new Uint8Array([211, 212]), - "944cd2847fb54558d4775db0485a50003111c8e5daa63fe722c6aa37": new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]) - }, - "Int8Array": { - "944cd2847fb54558d4775db0485a50003111c8e5daa63fe722c6aa37": new Int8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]) - }, - "ArrayBuffer": { - "6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4": new ArrayBuffer(0), - "283bb59af7081ed08197227d8f65b9591ffe1155be43e9550e57f941": new ArrayBuffer(1) - } - }, - sha512bits256: { - "ascii": { - "c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a": "", - "dd9d67b371519c339ed8dbd25af90e976a1eeefd4ad3d889005e532fc5bef04d": "The quick brown fox jumps over the lazy dog", - "1546741840f8a492b959d9b8b2344b9b0eb51b004bba35c0aebaac86d45264c3": "The quick brown fox jumps over the lazy dog." - }, - "ascii more than 64 bytes": { - "21e2e940930b23f1de6377086d07e22033c6bbf3fd9fbf4b62ec66e6c08c25be": "The MD5 message-digest algorithm is a widely used cryptographic hash function producing a 128-bit (16-byte) hash value, typically expressed in text format as a 32 digit hexadecimal number. MD5 has been utilized in a wide variety of cryptographic applications, and is also commonly used to verify data integrity." - }, - "UTF8": { - "b6dab29c16ec35ab34a5d92ff135b58de96741dda78b1009a2181cf8b45d2f72": "中文", - "122802ca08e39c2ef46f6a81379dc5683bd8aa074dfb54259f0add4d8b5504bc": "aécio", - "1032308151c0f4f5f8d4e0d96956352eb8ff87da98df8878d8795a858a7e7c08": "𠜎" - }, - "UTF8 more than 64 bytes": { - "d32a41d9858e45b68402f77cf9f3c3f992c36a4bffd230f78d666c87f97eaf7e": "訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一", - "bd1abad59e6b8ad69bc17b6e05aa13f0cb725467fbeb45b83d3e4094332d1367": "訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一(又譯雜湊演算法、摘要演算法等),主流程式語言普遍已有MD5的實作。" - }, - "special length": { - "99fb09c8564fbd52274cfaf1130ae02dad89efac9a31dc00e9bfc13db1ff4f56": "0123456780123456780123456780123456780123456780123456780", - "7a3204b58878f5a65a54f77e270d5df579a8016e0e472cc91833689c4cf8ca07": "01234567801234567801234567801234567801234567801234567801", - "f4aa5f7692e6fee7237510b9a886f7b7aa4098926b45eaf70672bdd6d316a633": "0123456780123456780123456780123456780123456780123456780123456780", - "3f8fc8ec35656592ce61bf44895b6d94077aae3bddd99236a0b04ccf936699ed": "01234567801234567801234567801234567801234567801234567801234567801234567", - "4cb330a62170d92fe3d03bcf9284b590cf08d38d3a3c1e661abba3641d0b7502": "012345678012345678012345678012345678012345678012345678012345678012345678" - }, - "Array": { - "c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a": [], - "547cf572033bb67ae341d010b348691ee9c550d07b796e0c6e6ad3503fa36cb3": [211, 212], - "dd9d67b371519c339ed8dbd25af90e976a1eeefd4ad3d889005e532fc5bef04d": [84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103], - "3f8fc8ec35656592ce61bf44895b6d94077aae3bddd99236a0b04ccf936699ed": [48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55] - }, - "Uint8Array": { - "547cf572033bb67ae341d010b348691ee9c550d07b796e0c6e6ad3503fa36cb3": new Uint8Array([211, 212]), - "dd9d67b371519c339ed8dbd25af90e976a1eeefd4ad3d889005e532fc5bef04d": new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]) - }, - "Int8Array": { - "dd9d67b371519c339ed8dbd25af90e976a1eeefd4ad3d889005e532fc5bef04d": new Int8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]) - }, - "ArrayBuffer": { - "c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a": new ArrayBuffer(0), - "10baad1713566ac2333467bddb0597dec9066120dd72ac2dcb8394221dcbe43d": new ArrayBuffer(1) - } - }, - sha512: { - "ascii": { - "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e": "", - "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6": "The quick brown fox jumps over the lazy dog", - "91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bbc6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed": "The quick brown fox jumps over the lazy dog." - }, - "ascii more than 64 bytes": { - "a8dedff31e3be9df6413ef5b4ecb93d62d3fbcb04297552eab5370e04afd45927854a4373037e81a50186e678d818c9ba824f4c850f3d0f02764af0252076979": "The MD5 message-digest algorithm is a widely used cryptographic hash function producing a 128-bit (16-byte) hash value, typically expressed in text format as a 32 digit hexadecimal number. MD5 has been utilized in a wide variety of cryptographic applications, and is also commonly used to verify data integrity." - }, - "UTF8": { - "8b88efc2ebbcbdad5ac2d65af05bec57bda25e71fd5fb25bbd892057a2755fbd05d8d8491cb2946febd5b0f124ffdfbaecf7e34946353c4f1b5ab29545895468": "中文", - "e1c6925243db76985abacaf9fa85e22697f549e67f65a36c88e4046a2260990ff9eefc3402396ea8dcbe8c592d8d5671bea612156eda38d3708d394bbd17d493": "aécio", - "f3e7ee9cdf7dbb52f7edd59ce3d49868c64f2b3aceceab060b8eaaebdf9de0dae5866d660e3319c5aad426a2176cb1703efc73eb24d1a90458ceda1b7f4e3940": "𠜎" - }, - "UTF8 more than 64 bytes": { - "6cb7f6d3381a187edadb43c7cdcfbbed4d2c213a7dce8ea08fe42b9882b64e643202b4974a6db94f94650ab9173d97c58bd59f6d19d27e01aab76d8d08855c65": "訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一", - "d24af1901aaf1458f089a6eddf784ce61c3012aee0df98bdb67ad2dc6b41a3b4051d40caac524373930ae396a2dde99a9204871b40892eea3e5f3c8d46da0c3c": "訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一(又譯雜湊演算法、摘要演算法等),主流程式語言普遍已有MD5的實作。" - }, - "special length": { - "6b4a72eb22d2d24c0a429dd99ce5835b134144ac5fce446f66dbf2f421dcc5f8a177e4774f4a48173c5640724b186c2c4112a80937b1167f3e7bb511f4c41b6a": "0123456780123456780123456780123456780123456780123456780", - "76f3cb2ed5b0b405479495b2d3576f4b469b6ffc4b06e3b512a658b84c1b91cf72c41c54d8714ecf19d04696f09e0034632fe98ae848ffd35b83c7e72399a590": "01234567801234567801234567801234567801234567801234567801", - "56d2391faebd8d69b067cd5c0cb364ffc2e2ab87ce5bb06a562b44c8dcb0b83816ad2c0c062537838992b181fadc43ff00e1ebb92ddb1129b81b4864bafb5f63": "0123456780123456780123456780123456780123456780123456780123456780", - "317ab88f192258711b8ae0197395b7a8191796fb41140c16c596699481149b47130e26b3bfa724227202fa8371752ca92e3cb9dd202caf29334038e0848cb43f": "01234567801234567801234567801234567801234567801234567801234567801234567", - "23880e96199df52b4386d190adddaa33cbf7e0bfa7d2067c60eb44ee103667fd002c32e184195fef65fd4178853b1c661d9f260d721df85872e5f645f4388841": "012345678012345678012345678012345678012345678012345678012345678012345678" - }, - "Array": { - "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e": [], - "8df0195b2807fdc8c7674c191562e9d0db38b257cc0d3df64669878fe5bb1bbaff53cc8898edcf46cbecb945dc71b6ad738da8ca6f3a824123a54afde5d1d5b0": [211, 212], - "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6": [84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103], - "317ab88f192258711b8ae0197395b7a8191796fb41140c16c596699481149b47130e26b3bfa724227202fa8371752ca92e3cb9dd202caf29334038e0848cb43f": [48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55] - }, - "Uint8Array": { - "8df0195b2807fdc8c7674c191562e9d0db38b257cc0d3df64669878fe5bb1bbaff53cc8898edcf46cbecb945dc71b6ad738da8ca6f3a824123a54afde5d1d5b0": new Uint8Array([211, 212]), - "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6": new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]) - }, - "Int8Array": { - "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6": new Int8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]) - }, - "ArrayBuffer": { - "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e": new ArrayBuffer(0), - "b8244d028981d693af7b456af8efa4cad63d282e19ff14942c246e50d9351d22704a802a71c3580b6370de4ceb293c324a8423342557d4e5c38438f0e36910ee": new ArrayBuffer(1) - } - }, - hmacSha512bits224: { - "Test Vectors": { - "b244ba01307c0e7a8ccaad13b1067a4cf6b961fe0c6a20bda3d92039": [ - [0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b], - "Hi There" - ], - "4a530b31a79ebcce36916546317c45f247d83241dfb818fd37254bde": [ - "Jefe", - "what do ya want for nothing?" - ], - "db34ea525c2c216ee5a6ccb6608bea870bbef12fd9b96a5109e2b6fc": [ - [0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa], - [0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd] - ], - "c2391863cda465c6828af06ac5d4b72d0b792109952da530e11a0d26": [ - [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19], - [0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd] - ], - "29bef8ce88b54d4226c3c7718ea9e32ace2429026f089e38cea9aeda": [ - [0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa], - "Test Using Larger Than Block-Size Key - Hash Key First" - ], - "82a9619b47af0cea73a8b9741355ce902d807ad87ee9078522a246e1": [ - [0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa], - "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm." - ] - }, - "UTF8": { - "24e1153464bf5ec62ad2eeeb88ff644f2441a124d1e16e8ae5fb1508": ["中文", "aécio"], - "7a08cecb4700304bc5c466acc1fb312d198374817052a03df07610c6": ["aécio", "𠜎"], - "697973678b7d0075676ec3cbbc19e343ed16fa20c14d8074b76b0861": ["𠜎", "中文"] - }, - "Uint8Array": { - "defdc4a1a6597147ea0c7d0a59ae0a5e64b9413a6400acac28aecdd1": [new Uint8Array(0), "Hi There"] - }, - "ArrayBuffer": { - "defdc4a1a6597147ea0c7d0a59ae0a5e64b9413a6400acac28aecdd1": [new ArrayBuffer(0), "Hi There"] - } - }, - hmacSha512bits256: { - "Test Vectors": { - "9f9126c3d9c3c330d760425ca8a217e31feae31bfe70196ff81642b868402eab": [ - [0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b], - "Hi There" - ], - "6df7b24630d5ccb2ee335407081a87188c221489768fa2020513b2d593359456": [ - "Jefe", - "what do ya want for nothing?" - ], - "229006391d66c8ecddf43ba5cf8f83530ef221a4e9401840d1bead5137c8a2ea": [ - [0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa], - [0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd] - ], - "36d60c8aa1d0be856e10804cf836e821e8733cbafeae87630589fd0b9b0a2f4c": [ - [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19], - [0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd] - ], - "87123c45f7c537a404f8f47cdbedda1fc9bec60eeb971982ce7ef10e774e6539": [ - [0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa], - "Test Using Larger Than Block-Size Key - Hash Key First" - ], - "6ea83f8e7315072c0bdaa33b93a26fc1659974637a9db8a887d06c05a7f35a66": [ - [0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa], - "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm." - ] - }, - "UTF8": { - "633400fa4bc12c3690efa218c90b56ab1af81b91ad62b57bdbe84988c51071e0": ["中文", "aécio"], - "80eff00e32e0c0813d4c04e296b5ac079ec896e673cc04b0ff14222e151ad0b0": ["aécio", "𠜎"], - "3f801c729e5330a0b91aecc751a26c35688a94989e2098c73bf0c6ac02b99e58": ["𠜎", "中文"] - }, - "Uint8Array": { - "1e08e33f9357abd2a3cfbc82a623d892bb6dccf175d22c0cf24269a7a59dfad6": [new Uint8Array(0), "Hi There"] - }, - "ArrayBuffer": { - "1e08e33f9357abd2a3cfbc82a623d892bb6dccf175d22c0cf24269a7a59dfad6": [new ArrayBuffer(0), "Hi There"] - } - }, - hmacSha512: { - "Test Vectors": { - "87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854": [ - [0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b], - "Hi There" - ], - "164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737": [ - "Jefe", - "what do ya want for nothing?" - ], - "fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb": [ - [0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa], - [0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd] - ], - "b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3dba91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd": [ - [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19], - [0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd] - ], - "80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b013783f8f3526b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec8b915a985d786598": [ - [0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa], - "Test Using Larger Than Block-Size Key - Hash Key First" - ], - "e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58": [ - [0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa], - "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm." - ] - }, - "UTF8": { - "e9e5906be0aecbc028a5fc759c9dbb86efc9a22950af8e678302a215aeee0b021edc50bbdd71c656730177b7e96c9a3bcf3cb9592bc84a5f3e8900cb67c7eca6": ["中文", "aécio"], - "d02a8d258d855967d5be47240bbedd986a31c29eb5beb35abdbe2725651bf33a195cdfaadb9e76dc4790c71dfea33f708afa04b9471d03f5f0db8440993b9612": ["aécio", "𠜎"], - "a443d463546586a5dd591ef848f0939c3a7089d63ef81d58ccc0a2611a1d374a39717d6893ea10d61ca0e87d5be7c80b29b2ed991c4a62e12d10c7f6b1b9d7ae": ["𠜎", "中文"] - }, - "Uint8Array": { - "f7688a104326d36c1940f6d28d746c0661d383e0d14fe8a04649444777610f5dd9565a36846ab9e9e734cf380d3a070d8ef021b5f3a50c481710a464968e3419": [new Uint8Array(0), "Hi There"] - }, - "ArrayBuffer": { - "f7688a104326d36c1940f6d28d746c0661d383e0d14fe8a04649444777610f5dd9565a36846ab9e9e734cf380d3a070d8ef021b5f3a50c481710a464968e3419": [new ArrayBuffer(0), "Hi There"] - } - }, -}; - -const methods = ["array", "arrayBuffer", "digest", "hex"] as const; - -for (const method of methods) { - for (const [name, tests] of Object.entries(fixtures.sha512bits224)) { - let i = 1; - for (const [expected, message] of Object.entries(tests)) { - Deno.test({ - name: `sha512/224.${method}() - ${name} - #${i++}`, - fn() { - const algorithm = new Sha512(224); - algorithm.update(message); - const actual = method === "hex" - ? algorithm[method]() - : toHexString(algorithm[method]()); - assertEquals(actual, expected); - }, - }); - } - } -} - -for (const method of methods) { - for (const [name, tests] of Object.entries(fixtures.sha512bits256)) { - let i = 1; - for (const [expected, message] of Object.entries(tests)) { - Deno.test({ - name: `sha512/256.${method}() - ${name} - #${i++}`, - fn() { - const algorithm = new Sha512(256); - algorithm.update(message); - const actual = method === "hex" - ? algorithm[method]() - : toHexString(algorithm[method]()); - assertEquals(actual, expected); - }, - }); - } - } -} - -for (const method of methods) { - for (const [name, tests] of Object.entries(fixtures.sha512)) { - let i = 1; - for (const [expected, message] of Object.entries(tests)) { - Deno.test({ - name: `sha512.${method}() - ${name} - #${i++}`, - fn() { - const algorithm = new Sha512(); - algorithm.update(message); - const actual = method === "hex" - ? algorithm[method]() - : toHexString(algorithm[method]()); - assertEquals(actual, expected); - }, - }); - } - } -} - -for (const method of methods) { - for (const [name, tests] of Object.entries(fixtures.hmacSha512bits224)) { - let i = 1; - for (const [expected, [key, message]] of Object.entries(tests)) { - Deno.test({ - name: `hmacSha512/224.${method}() - ${name} - #${i++}`, - fn() { - const algorithm = new HmacSha512(key, 224); - algorithm.update(message); - const actual = method === "hex" - ? algorithm[method]() - : toHexString(algorithm[method]()); - assertEquals(actual, expected); - }, - }); - } - } -} - -for (const method of methods) { - for (const [name, tests] of Object.entries(fixtures.hmacSha512bits256)) { - let i = 1; - for (const [expected, [key, message]] of Object.entries(tests)) { - Deno.test({ - name: `hmacSha512/256.${method}() - ${name} - #${i++}`, - fn() { - const algorithm = new HmacSha512(key, 256); - algorithm.update(message); - const actual = method === "hex" - ? algorithm[method]() - : toHexString(algorithm[method]()); - assertEquals(actual, expected); - }, - }); - } - } -} - -for (const method of methods) { - for (const [name, tests] of Object.entries(fixtures.hmacSha512)) { - let i = 1; - for (const [expected, [key, message]] of Object.entries(tests)) { - Deno.test({ - name: `hmacSha512.${method}() - ${name} - #${i++}`, - fn() { - const algorithm = new HmacSha512(key); - algorithm.update(message); - const actual = method === "hex" - ? algorithm[method]() - : toHexString(algorithm[method]()); - assertEquals(actual, expected); - }, - }); - } - } -} - -Deno.test("[hash/sha512] test Uint8Array from Reader", async () => { - const data = await Deno.readFile(join(testdataDir, "hashtest")); - const hash = new Sha512().update(data).hex(); - assertEquals( - hash, - "ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff", - ); -}); diff --git a/std/hash/test.ts b/std/hash/test.ts deleted file mode 100644 index 31540e384..000000000 --- a/std/hash/test.ts +++ /dev/null @@ -1,316 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -import { assertEquals, assertThrows } from "../testing/asserts.ts"; -import { createHash, SupportedAlgorithm } from "./mod.ts"; - -const millionAs = "a".repeat(1000000); - -const testSetHex: Record<string, string[][]> = { - md5: [ - ["", "d41d8cd98f00b204e9800998ecf8427e"], - ["abc", "900150983cd24fb0d6963f7d28e17f72"], - ["deno", "c8772b401bc911da102a5291cc4ec83b"], - [ - "The quick brown fox jumps over the lazy dog", - "9e107d9d372bb6826bd81d3542a419d6", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "3b0c8ac703f828b04c6c197006d17218", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "014842d480b571495a4a0363793f7367", - ], - [millionAs, "7707d6ae4e027c70eea2a935c2296f21"], - ], - sha1: [ - ["", "da39a3ee5e6b4b0d3255bfef95601890afd80709"], - ["abc", "a9993e364706816aba3e25717850c26c9cd0d89d"], - ["deno", "bb3d8e712d9e7ad4af08d4a38f3f52d9683d58eb"], - [ - "The quick brown fox jumps over the lazy dog", - "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "c2db330f6083854c99d4b5bfb6e8f29f201be699", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "0098ba824b5c16427bd7a1122a5a442a25ec644d", - ], - [millionAs, "34aa973cd4c4daa4f61eeb2bdbad27316534016f"], - ], - sha256: [ - ["", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"], - ["abc", "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"], - [ - "deno", - "e872e7bd2ae6abcf13a4c834029a342c882c1162ebf77b6720968b2000312ffb", - ], - [ - "The quick brown fox jumps over the lazy dog", - "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "b35439a4ac6f0948b6d6f9e3c6af0f5f590ce20f1bde7090ef7970686ec6738a", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "ffe054fe7ae0cb6dc65c3af9b61d5209f439851db43d0ba5997337df154668eb", - ], - [ - millionAs, - "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0", - ], - ], - sha512: [ - [ - "", - "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", - ], - [ - "abc", - "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f", - ], - [ - "deno", - "05b6ef7b13673c57c455d968cb7acbdd4fe10e24f25520763d69025d768d14124987b14e3aff8ff1565aaeba1c405fc89cc435938ff46a426f697b0f509e3799", - ], - [ - "The quick brown fox jumps over the lazy dog", - "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "962b64aae357d2a4fee3ded8b539bdc9d325081822b0bfc55583133aab44f18bafe11d72a7ae16c79ce2ba620ae2242d5144809161945f1367f41b3972e26e04", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "01d35c10c6c38c2dcf48f7eebb3235fb5ad74a65ec4cd016e2354c637a8fb49b695ef3c1d6f7ae4cd74d78cc9c9bcac9d4f23a73019998a7f73038a5c9b2dbde", - ], - [ - millionAs, - "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b", - ], - ], - "sha3-256": [ - ["", "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"], - ["abc", "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532"], - [ - "deno", - "74a6286af90f8775d74080f864cf80b11eecf6f14d325c5ef8c9f7ccc8055517", - ], - [ - "The quick brown fox jumps over the lazy dog", - "69070dda01975c8c120c3aada1b282394e7f032fa9cf32f4cb2259a0897dfc04", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "f6fe8de5c8f5014786f07e9f7b08130f920dd55e587d47021686b26cf2323deb", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "043d104b5480439c7acff8831ee195183928d9b7f8fcb0c655a086a87923ffee", - ], - [ - millionAs, - "5c8875ae474a3634ba4fd55ec85bffd661f32aca75c6d699d0cdcb6c115891c1", - ], - ], - "sha3-512": [ - [ - "", - "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26", - ], - [ - "abc", - "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0", - ], - [ - "deno", - "9e248199d744a8d810e7fda8207f98f27453bd6cb5a02965b5477d3d07516bbac6831009eedddadc8901d742dbfe3fd4afa770230a84e4d51bf30a0c99efa03c", - ], - [ - "The quick brown fox jumps over the lazy dog", - "01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "302d75b7947aa354a54872df954dc0dfe673cf60faedebdea7e9b22263a3bdf39e346a4f2868639836955396f186a67b02ec8e3365bdf59867070f81849c2c35", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "2141e94c719955872c455c83eb83e7618a9b523a0ee9f118e794fbff8b148545c8e8caabef08d8cfdb1dfb36b4dd81cc48bfc77e7f85632197b882fd9c4384e0", - ], - [ - millionAs, - "3c3a876da14034ab60627c077bb98f7e120a2a5370212dffb3385a18d4f38859ed311d0a9d5141ce9cc5c66ee689b266a8aa18ace8282a0e0db596c90b0a7b87", - ], - ], -}; - -const testSetBase64: Record<string, string[][]> = { - md5: [ - ["", "1B2M2Y8AsgTpgAmY7PhCfg=="], - ["abc", "kAFQmDzST7DWlj99KOF/cg=="], - ["deno", "yHcrQBvJEdoQKlKRzE7IOw=="], - ["The quick brown fox jumps over the lazy dog", "nhB9nTcrtoJr2B01QqQZ1g=="], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "OwyKxwP4KLBMbBlwBtFyGA==", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "AUhC1IC1cUlaSgNjeT9zZw==", - ], - [millionAs, "dwfWrk4CfHDuoqk1wilvIQ=="], - ], - sha1: [ - ["", "2jmj7l5rSw0yVb/vlWAYkK/YBwk="], - ["abc", "qZk+NkcGgWq6PiVxeFDCbJzQ2J0="], - ["deno", "uz2OcS2eetSvCNSjjz9S2Wg9WOs="], - [ - "The quick brown fox jumps over the lazy dog", - "L9ThxnotKPzthJ7hu3bnORuT6xI=", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "wtszD2CDhUyZ1LW/tujynyAb5pk=", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "AJi6gktcFkJ716ESKlpEKiXsZE0=", - ], - [millionAs, "NKqXPNTE2qT2Husr260nMWU0AW8="], - ], - sha256: [ - ["", "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="], - ["abc", "ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0="], - ["deno", "6HLnvSrmq88TpMg0Apo0LIgsEWLr93tnIJaLIAAxL/s="], - [ - "The quick brown fox jumps over the lazy dog", - "16j7swfXgJRpypq8sAguT41WUeRtPNt2LQLQvzfJ5ZI=", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "s1Q5pKxvCUi21vnjxq8PX1kM4g8b3nCQ73lwaG7Gc4o=", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "/+BU/nrgy23GXDr5th1SCfQ5hR20PQulmXM33xVGaOs=", - ], - [millionAs, "zcduXJkU+5KBocfihNc+Z/GAmkiklyAOBG05zMcRLNA="], - ], - sha512: [ - [ - "", - "z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==", - ], - [ - "abc", - "3a81oZNherrMQXNJriBBMRLm+k6JqX6iCp7u5ktV05ohkpkqJ0/BqDa6PCOj/uu9RU1EI2Q86A4qmslPpUyknw==", - ], - [ - "deno", - "BbbvexNnPFfEVdloy3rL3U/hDiTyVSB2PWkCXXaNFBJJh7FOOv+P8VZarrocQF/InMQ1k4/0akJvaXsPUJ43mQ==", - ], - [ - "The quick brown fox jumps over the lazy dog", - "B+VH2VhvanP3P7rAQ17XaVEhj7fQyNeIownXhUNru2Quk6JSqVTyORJUfR6KO17W4b/XCXghIz+gU489uFT+5g==", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "litkquNX0qT+497YtTm9ydMlCBgisL/FVYMTOqtE8Yuv4R1yp64Wx5ziumIK4iQtUUSAkWGUXxNn9Bs5cuJuBA==", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "AdNcEMbDjC3PSPfuuzI1+1rXSmXsTNAW4jVMY3qPtJtpXvPB1veuTNdNeMycm8rJ1PI6cwGZmKf3MDilybLb3g==", - ], - [ - millionAs, - "5xhIPQznaWROLkLHvBW0Y44fmLE7IEQoVjKoA6+pc+veD/JEh36mCkywQyzld8Mb6wCcXCxJqi5OrbIXrYzAmw==", - ], - ], - "sha3-256": [ - ["", "p//G+L8e12ZRwUdWoGHWYvWA/03kO0n6gtgKS4D4Q0o="], - ["abc", "Ophdp0/iJbIEXBcta9OQvYVfCG4+nVJbRr/iRRFDFTI="], - ["deno", "dKYoavkPh3XXQID4ZM+AsR7s9vFNMlxe+Mn3zMgFVRc="], - [ - "The quick brown fox jumps over the lazy dog", - "aQcN2gGXXIwSDDqtobKCOU5/Ay+pzzL0yyJZoIl9/AQ=", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "9v6N5cj1AUeG8H6fewgTD5IN1V5YfUcCFoaybPIyPes=", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "BD0QS1SAQ5x6z/iDHuGVGDko2bf4/LDGVaCGqHkj/+4=", - ], - [millionAs, "XIh1rkdKNjS6T9VeyFv/1mHzKsp1xtaZ0M3LbBFYkcE="], - ], - "sha3-512": [ - [ - "", - "pp9zzKI6msXItWfcGFp1bpfJghZP4lhZ4NHcwUdcgKYVshI68fX5TBHj6UAsOsVY9QAZnZW20+MBdYWGKB3NJg==", - ], - [ - "abc", - "t1GFCxpXFopWk82SS2sJbgj2IYJ0RPcNiE9dAkDScS4Q4RbpGSrzyRp+xXZH45NAVzQLTPQI1aVlkvgnTuxT8A==", - ], - [ - "deno", - "niSBmddEqNgQ5/2oIH+Y8nRTvWy1oClltUd9PQdRa7rGgxAJ7t3a3IkB10Lb/j/Ur6dwIwqE5NUb8woMme+gPA==", - ], - [ - "The quick brown fox jumps over the lazy dog", - "Ad7dXeTvFGQkRbpfW5fBXke5rZMTJuSwcnzZTO/ET/8j8Hv1QxOZObSRKMr0Ntwb3uVPyyQCOgjZQD+bS/DUUA==", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "MC11t5R6o1SlSHLflU3A3+Zzz2D67evep+myImOjvfOeNGpPKGhjmDaVU5bxhqZ7AuyOM2W99ZhnBw+BhJwsNQ==", - ], - [ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "IUHpTHGZVYcsRVyD64PnYYqbUjoO6fEY55T7/4sUhUXI6Mqr7wjYz9sd+za03YHMSL/Hfn+FYyGXuIL9nEOE4A==", - ], - [ - millionAs, - "PDqHbaFANKtgYnwHe7mPfhIKKlNwIS3/szhaGNTziFntMR0KnVFBzpzFxm7mibJmqKoYrOgoKg4NtZbJCwp7hw==", - ], - ], -}; - -Deno.test("[hash/all/hex] testAllHex", () => { - for (const algorithm in testSetHex) { - for (const [input, output] of testSetHex[algorithm]) { - const hash = createHash(algorithm as SupportedAlgorithm); - assertEquals(hash.update(input).toString(), output); - } - } -}); - -Deno.test("[hash/all/base64] testAllHex", () => { - for (const algorithm in testSetBase64) { - for (const [input, output] of testSetBase64[algorithm]) { - const hash = createHash(algorithm as SupportedAlgorithm); - assertEquals(hash.update(input).toString("base64"), output); - } - } -}); - -Deno.test("[hash/double_digest] testDoubleDigest", () => { - assertThrows( - (): void => { - const hash = createHash("md5"); - hash.update("test"); - const h1 = hash.digest(); - const h2 = hash.digest(); - assertEquals(h1, h2); - }, - Error, - "hash: already digested", - ); -}); diff --git a/std/hash/testdata/hashtest b/std/hash/testdata/hashtest deleted file mode 100644 index 30d74d258..000000000 --- a/std/hash/testdata/hashtest +++ /dev/null @@ -1 +0,0 @@ -test
\ No newline at end of file |