import { bytes, hex } from './convert'
-const { crypto } = globalThis
-const MIN = 16
-const MAX = 32
-const MOD = 4
-
/**
* Represents a cryptographically strong source of entropy suitable for use in
* BIP-39 mnemonic phrase generation and consequently BIP-44 key derivation.
*/
export class Entropy {
static #isInternal: boolean = false
+ static MIN: 16 = 16
+ static MAX: 32 = 32
+ static MOD: 4 = 4
#bytes: Uint8Array<ArrayBuffer>
get bits (): string { return bytes.toBin(this.#bytes) }
if (typeof size !== 'number') {
throw new TypeError(`Entropy cannot use ${typeof size} as a size`)
}
- if (size < MIN || size > MAX) {
- throw new RangeError(`Entropy must be ${MIN}-${MAX} bytes`)
+ if (size < this.MIN || size > this.MAX) {
+ throw new RangeError(`Entropy must be ${this.MIN}-${this.MAX} bytes`)
}
- if (size % MOD !== 0) {
- throw new RangeError(`Entropy must be a multiple of ${MOD} bytes`)
+ if (size % this.MOD !== 0) {
+ throw new RangeError(`Entropy must be a multiple of ${this.MOD} bytes`)
}
}
Entropy.#isInternal = true
- resolve(new this(crypto.getRandomValues(new Uint8Array(size ?? MAX))))
+ resolve(new this(globalThis.crypto.getRandomValues(new Uint8Array(size ?? this.MAX))))
})
}
static async import (input: string | ArrayBuffer | Uint8Array<ArrayBuffer>): Promise<Entropy> {
return new Promise((resolve, reject) => {
if (typeof input === 'string') {
- if (input.length < MIN * 2 || input.length > MAX * 2) {
- throw new RangeError(`Entropy must be ${MIN * 2}-${MAX * 2} characters`)
+ if (input.length < this.MIN * 2 || input.length > this.MAX * 2) {
+ throw new RangeError(`Entropy must be ${this.MIN * 2}-${this.MAX * 2} characters`)
}
- if (input.length % MOD * 2 !== 0) {
- throw new RangeError(`Entropy must be a multiple of ${MOD * 2} characters`)
+ if (input.length % this.MOD * 2 !== 0) {
+ throw new RangeError(`Entropy must be a multiple of ${this.MOD * 2} characters`)
}
if (!/^[0-9a-fA-F]+$/i.test(input)) {
throw new RangeError('Entropy contains invalid hexadecimal characters')
}
if (input instanceof ArrayBuffer) {
- if (input.byteLength < MIN || input.byteLength > MAX) {
- throw new Error(`Entropy must be ${MIN}-${MAX} bytes`)
+ if (input.byteLength < this.MIN || input.byteLength > this.MAX) {
+ throw new Error(`Entropy must be ${this.MIN}-${this.MAX} bytes`)
}
- if (input.byteLength % MOD !== 0) {
- throw new RangeError(`Entropy must be a multiple of ${MOD} bytes`)
+ if (input.byteLength % this.MOD !== 0) {
+ throw new RangeError(`Entropy must be a multiple of ${this.MOD} bytes`)
}
Entropy.#isInternal = true
resolve(new this(new Uint8Array(input)))
if (!(input.buffer instanceof ArrayBuffer)) {
throw new TypeError(`Entropy imported bytes must be backed by an ArrayBuffer.`)
}
- if (input.length < MIN || input.length > MAX) {
- throw new Error(`Entropy must be ${MIN}-${MAX} bytes`)
+ if (input.length < this.MIN || input.length > this.MAX) {
+ throw new Error(`Entropy must be ${this.MIN}-${this.MAX} bytes`)
}
- if (input.length % MOD !== 0) {
- throw new RangeError(`Entropy must be a multiple of ${MOD} bytes`)
+ if (input.length % this.MOD !== 0) {
+ throw new RangeError(`Entropy must be a multiple of ${this.MOD} bytes`)
}
Entropy.#isInternal = true
resolve(new this(input))
*/
destroy (): boolean {
try {
- crypto.getRandomValues(this.#bytes)
+ globalThis.crypto.getRandomValues(this.#bytes)
return true
} catch (err) {
return false