*/
export class Blake2b {
- static #OUTBYTES_MIN: number = 1
- static #OUTBYTES_MAX: number = 64
- static #KEYBYTES_MIN: number = 1
- static #KEYBYTES_MAX: number = 64
- static #SALTBYTES: number = 16
- static #PERSONALBYTES: number = 16
- static #IV: bigint[] = [
- 0x6a09e667f3bcc908n,
- 0xbb67ae8584caa73bn,
- 0x3c6ef372fe94f82bn,
- 0xa54ff53a5f1d36f1n,
- 0x510e527fade682d1n,
- 0x9b05688c2b3e6c1fn,
- 0x1f83d9abfb41bd6bn,
- 0x5be0cd19137e2179n
- ]
- static #SIGMA: number[][] = [
- [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
- [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3],
- [11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4],
- [7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8],
- [9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13],
- [2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9],
- [12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11],
- [13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10],
- [6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5],
- [10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0],
- [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
- [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3]
- ]
-
- static #toHex (buf: Uint8Array): string {
- let str = ''
- for (let i = 0; i < buf.length; i++) {
- str += buf[i].toString(16).padStart(2, '0')
- }
- return str
+ static get OUTBYTES_MIN (): 1 { return 1 }
+ static get OUTBYTES_MAX (): 64 { return 64 }
+ static get KEYBYTES_MIN (): 1 { return 1 }
+ static get KEYBYTES_MAX (): 64 { return 64 }
+ static get SALTBYTES (): 16 { return 16 }
+ static get PERSONALBYTES (): 16 { return 16 }
+ static get IV (): bigint[] {
+ return [
+ 0x6a09e667f3bcc908n,
+ 0xbb67ae8584caa73bn,
+ 0x3c6ef372fe94f82bn,
+ 0xa54ff53a5f1d36f1n,
+ 0x510e527fade682d1n,
+ 0x9b05688c2b3e6c1fn,
+ 0x1f83d9abfb41bd6bn,
+ 0x5be0cd19137e2179n
+ ]
+ }
+ static get SIGMA (): number[][] {
+ return [
+ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
+ [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3],
+ [11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4],
+ [7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8],
+ [9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13],
+ [2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9],
+ [12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11],
+ [13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10],
+ [6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5],
+ [10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0],
+ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
+ [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3]
+ ]
}
#G (r: number, i: number, a: number, b: number, c: number, d: number): void {
- this.#v[a] += this.#v[b] + this.#m[Blake2b.#SIGMA[r][2 * i + 0]]
+ this.#v[a] += this.#v[b] + this.#m[Blake2b.SIGMA[r][2 * i + 0]]
this.#v[d] ^= this.#v[a]
this.#v[d] = (this.#v[d] >> 32n) | (this.#v[d] << 32n)
this.#v[c] += this.#v[d]
this.#v[b] ^= this.#v[c]
this.#v[b] = (this.#v[b] >> 24n) | (this.#v[b] << 40n)
- this.#v[a] += this.#v[b] + this.#m[Blake2b.#SIGMA[r][2 * i + 1]]
+ this.#v[a] += this.#v[b] + this.#m[Blake2b.SIGMA[r][2 * i + 1]]
this.#v[d] ^= this.#v[a]
this.#v[d] = (this.#v[d] >> 16n) | (this.#v[d] << 48n)
this.#v[c] += this.#v[d]
// init work variables
for (let i = 0; i < 8; i++) {
this.#v[i] = this.#h[i]
- this.#v[i + 8] = Blake2b.#IV[i]
+ this.#v[i + 8] = Blake2b.IV[i]
}
// lo 64 bits of counter
if (typeof length !== 'number') {
throw new TypeError(`length must be number`)
}
- if (length < Blake2b.#OUTBYTES_MIN || length > Blake2b.#OUTBYTES_MAX) {
- throw new RangeError(`length must be ${Blake2b.#OUTBYTES_MIN}-${Blake2b.#OUTBYTES_MAX} bytes`)
+ if (length < Blake2b.OUTBYTES_MIN || length > Blake2b.OUTBYTES_MAX) {
+ throw new RangeError(`length must be ${Blake2b.OUTBYTES_MIN}-${Blake2b.OUTBYTES_MAX} bytes`)
}
if (key != null) {
if (!(key instanceof Uint8Array)) {
throw new TypeError(`key must be Uint8Array or Buffer`)
}
- if (key.length < Blake2b.#KEYBYTES_MIN || key.length > Blake2b.#KEYBYTES_MAX) {
- throw new RangeError(`key must be ${Blake2b.#KEYBYTES_MIN}-${Blake2b.#KEYBYTES_MAX} bytes`)
+ if (key.length < Blake2b.KEYBYTES_MIN || key.length > Blake2b.KEYBYTES_MAX) {
+ throw new RangeError(`key must be ${Blake2b.KEYBYTES_MIN}-${Blake2b.KEYBYTES_MAX} bytes`)
}
}
if (salt != null) {
if (!(salt instanceof Uint8Array)) {
throw new TypeError(`salt must be Uint8Array or Buffer`)
}
- if (salt.length !== Blake2b.#SALTBYTES) {
- throw new RangeError(`salt must be ${Blake2b.#SALTBYTES} bytes`)
+ if (salt.length !== Blake2b.SALTBYTES) {
+ throw new RangeError(`salt must be ${Blake2b.SALTBYTES} bytes`)
}
}
if (personal != null) {
if (!(personal instanceof Uint8Array)) {
throw new TypeError(`personal must be Uint8Array or Buffer`)
}
- if (personal.length !== Blake2b.#PERSONALBYTES) {
- throw new RangeError(`personal must be ${Blake2b.#PERSONALBYTES} bytes`)
+ if (personal.length !== Blake2b.PERSONALBYTES) {
+ throw new RangeError(`personal must be ${Blake2b.PERSONALBYTES} bytes`)
}
}
// initialize hash state
for (let i = 0; i < 8; i++) {
- this.#h[i] = Blake2b.#IV[i] ^ this.#parameter_view.getBigUint64(i * 8, true)
+ this.#h[i] = Blake2b.IV[i] ^ this.#parameter_view.getBigUint64(i * 8, true)
}
// key the hash, if applicable
return this
}
- digest (): Uint8Array<ArrayBuffer>
- digest (out: 'hex'): string
- digest (out: 'binary' | Uint8Array<ArrayBuffer>): Uint8Array<ArrayBuffer>
- digest (out?: unknown): string | Uint8Array<ArrayBuffer> {
- if (out !== undefined && out !== 'binary' && out !== 'hex' && !(out instanceof Uint8Array)) {
- throw new TypeError('out must be "binary", "hex", Uint8Array, or Buffer')
- }
- const buf = (out === undefined || typeof out === 'string') ? new Uint8Array(this.#outlen) : new Uint8Array(out)
+ digest (): Uint8Array<ArrayBuffer> {
+ const buf = new Uint8Array(this.#outlen)
if (buf.length < this.#outlen) throw new RangeError('out must have at least outlen bytes of space')
this.#blake2bFinal(buf)
- return (out === 'hex')
- ? Blake2b.#toHex(buf)
- : buf
+ return buf
}
}