Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@scure/base

Package Overview
Dependencies
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@scure/base - npm Package Compare versions

Comparing version 1.1.9 to 1.2.0

250

index.ts
/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */
// Utilities
/**
* @__NO_SIDE_EFFECTS__
*/
export function assertNumber(n: number) {

@@ -21,8 +18,34 @@ if (!Number.isSafeInteger(n)) throw new Error(`Wrong integer: ${n}`);

function isBytes(a: unknown): a is Uint8Array {
return (
a instanceof Uint8Array ||
(a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array')
);
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
}
function isArrayOf(type: 'string' | 'number', arr: any[]) {
if (!Array.isArray(arr)) return false;
if (arr.length === 0) return true;
if (type === 'string') return arr.every((item) => typeof item === 'string');
if (type === 'number') return arr.every((item) => Number.isSafeInteger(item));
return false;
}
// no abytes: seems to have 10% slowdown. Why?!
function afn(input: Function): input is Function {
if (typeof input !== 'function') throw new Error('function expected');
return true;
}
function astr(label: string, input: unknown): input is string {
if (typeof input !== 'string') throw new Error(`${label}: string expected`);
return true;
}
function astrArr(label: string, input: string[]): input is string[] {
if (!isArrayOf('string', input)) throw new Error(`${label}: array of strings expected`);
return true;
}
function anumArr(label: string, input: number[]): input is number[] {
if (!isArrayOf('number', input)) throw new Error(`${label}: array of strings expected`);
return true;
}
// TODO: some recusive type inference so it would check correct order of input/output inside rest?

@@ -44,5 +67,2 @@ // like <string, number>, <number, bytes>, <bytes, float>

/**
* @__NO_SIDE_EFFECTS__
*/
function chain<T extends Chain & AsChain<T>>(...args: T): Coder<Input<First<T>>, Output<Last<T>>> {

@@ -59,29 +79,32 @@ const id = (a: any) => a;

type Alphabet = string[] | string;
/**
* Encodes integer radix representation to array of strings using alphabet and back
* @__NO_SIDE_EFFECTS__
* Encodes integer radix representation to array of strings using alphabet and back.
* Could also be array of strings.
*/
function alphabet(alphabet: Alphabet): Coder<number[], string[]> {
function alphabet(letters: string | string[]): Coder<number[], string[]> {
// mapping 1 to "b"
const lettersA = typeof letters === 'string' ? letters.split('') : letters;
const len = lettersA.length;
astrArr('alphabet', lettersA);
// mapping "b" to 1
const indexes = new Map(lettersA.map((l, i) => [l, i]));
return {
encode: (digits: number[]) => {
if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
throw new Error('alphabet.encode input should be an array of numbers');
if (!Array.isArray(digits)) throw new Error('array expected');
return digits.map((i) => {
assertNumber(i);
if (i < 0 || i >= alphabet.length)
throw new Error(`Digit index outside alphabet: ${i} (alphabet: ${alphabet.length})`);
return alphabet[i]!;
if (!Number.isSafeInteger(i) || i < 0 || i >= len)
throw new Error(
`alphabet.encode: digit index outside alphabet "${i}". Allowed: ${letters}`
);
return lettersA[i]!;
});
},
decode: (input: string[]) => {
if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string'))
throw new Error('alphabet.decode input should be array of strings');
decode: (input: string[]): number[] => {
if (!Array.isArray(input)) throw new Error('array expected');
return input.map((letter) => {
if (typeof letter !== 'string')
throw new Error(`alphabet.decode: not string element=${letter}`);
const index = alphabet.indexOf(letter);
if (index === -1) throw new Error(`Unknown letter: "${letter}". Allowed: ${alphabet}`);
return index;
astr('alphabet.decode', letter);
const i = indexes.get(letter);
if (i === undefined) throw new Error(`Unknown letter: "${letter}". Allowed: ${letters}`);
return i;
});

@@ -92,17 +115,11 @@ },

/**
* @__NO_SIDE_EFFECTS__
*/
function join(separator = ''): Coder<string[], string> {
if (typeof separator !== 'string') throw new Error('join separator should be string');
astr('join', separator);
return {
encode: (from) => {
if (!Array.isArray(from) || (from.length && typeof from[0] !== 'string'))
throw new Error('join.encode input should be array of strings');
for (let i of from)
if (typeof i !== 'string') throw new Error(`join.encode: non-string input=${i}`);
astrArr('join.decode', from);
return from.join(separator);
},
decode: (to) => {
if (typeof to !== 'string') throw new Error('join.decode input should be string');
astr('join.decode', to);
return to.split(separator);

@@ -115,13 +132,9 @@ },

* Pad strings array so it has integer number of bits
* @__NO_SIDE_EFFECTS__
*/
function padding(bits: number, chr = '='): Coder<string[], string[]> {
assertNumber(bits);
if (typeof chr !== 'string') throw new Error('padding chr should be string');
astr('padding', chr);
return {
encode(data: string[]): string[] {
if (!Array.isArray(data) || (data.length && typeof data[0] !== 'string'))
throw new Error('padding.encode input should be array of strings');
for (let i of data)
if (typeof i !== 'string') throw new Error(`padding.encode: non-string input=${i}`);
astrArr('padding.encode', data);
while ((data.length * bits) % 8) data.push(chr);

@@ -131,12 +144,10 @@ return data;

decode(input: string[]): string[] {
if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string'))
throw new Error('padding.encode input should be array of strings');
for (let i of input)
if (typeof i !== 'string') throw new Error(`padding.decode: non-string input=${i}`);
astrArr('padding.decode', input);
let end = input.length;
if ((end * bits) % 8)
throw new Error('Invalid padding: string should have whole number of bytes');
throw new Error('padding: invalid, string should have whole number of bytes');
for (; end > 0 && input[end - 1] === chr; end--) {
if (!(((end - 1) * bits) % 8))
throw new Error('Invalid padding: string has too much padding');
const last = end - 1;
const byte = last * bits;
if (byte % 8 === 0) throw new Error('padding: invalid, string has too much padding');
}

@@ -148,7 +159,4 @@ return input.slice(0, end);

/**
* @__NO_SIDE_EFFECTS__
*/
function normalize<T>(fn: (val: T) => T): Coder<T, T> {
if (typeof fn !== 'function') throw new Error('normalize fn should be function');
afn(fn);
return { encode: (from: T) => from, decode: (to: T) => fn(to) };

@@ -159,3 +167,2 @@ }

* Slow: O(n^2) time complexity
* @__NO_SIDE_EFFECTS__
*/

@@ -175,6 +182,7 @@ function convertRadix(data: number[], from: number, to: number): number[] {

});
const dlen = digits.length;
while (true) {
let carry = 0;
let done = true;
for (let i = pos; i < digits.length; i++) {
for (let i = pos; i < dlen; i++) {
const digit = digits[i]!;

@@ -189,4 +197,5 @@ const digitBase = from * carry + digit;

}
let div = digitBase / to;
carry = digitBase % to;
const rounded = Math.floor(digitBase / to);
const rounded = Math.floor(div);
digits[i] = rounded;

@@ -206,8 +215,12 @@ if (!Number.isSafeInteger(rounded) || rounded * to + carry !== digitBase)

const gcd = /* @__NO_SIDE_EFFECTS__ */ (a: number, b: number): number => (!b ? a : gcd(b, a % b));
const gcd = (a: number, b: number): number => (b === 0 ? a : gcd(b, a % b));
const radix2carry = /*@__NO_SIDE_EFFECTS__ */ (from: number, to: number) =>
from + (to - gcd(from, to));
const powers: number[] = /* @__PURE__ */ (() => {
let res = [];
for (let i = 0; i < 40; i++) res.push(2 ** i);
return res;
})();
/**
* Implemented with numbers, because BigInt is 5x slower
* @__NO_SIDE_EFFECTS__
*/

@@ -225,7 +238,8 @@ function convertRadix2(data: number[], from: number, to: number, padding: boolean): number[] {

let pos = 0; // bitwise position in current element
const mask = 2 ** to - 1;
const max = powers[from]!;
const mask = powers[to]! - 1;
const res: number[] = [];
for (const n of data) {
assertNumber(n);
if (n >= 2 ** from) throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);
if (n >= max) throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);
carry = (carry << from) | n;

@@ -235,7 +249,9 @@ if (pos + from > 32) throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`);

for (; pos >= to; pos -= to) res.push(((carry >> (pos - to)) & mask) >>> 0);
carry &= 2 ** pos - 1; // clean carry, otherwise it will cause overflow
const pow = powers[pos];
if (pow === undefined) throw new Error('invalid carry');
carry &= pow - 1; // clean carry, otherwise it will cause overflow
}
carry = (carry << (to - pos)) & mask;
if (!padding && pos >= from) throw new Error('Excess padding');
if (!padding && carry) throw new Error(`Non-zero padding: ${carry}`);
if (!padding && carry > 0) throw new Error(`Non-zero padding: ${carry}`);
if (padding && pos > 0) res.push(carry >>> 0);

@@ -245,16 +261,13 @@ return res;

/**
* @__NO_SIDE_EFFECTS__
*/
function radix(num: number): Coder<Uint8Array, number[]> {
assertNumber(num);
const _256 = 2 ** 8;
return {
encode: (bytes: Uint8Array) => {
if (!isBytes(bytes)) throw new Error('radix.encode input should be Uint8Array');
return convertRadix(Array.from(bytes), 2 ** 8, num);
return convertRadix(Array.from(bytes), _256, num);
},
decode: (digits: number[]) => {
if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
throw new Error('radix.decode input should be array of numbers');
return Uint8Array.from(convertRadix(digits, num, 2 ** 8));
anumArr('radix.decode', digits);
return Uint8Array.from(convertRadix(digits, num, _256));
},

@@ -267,3 +280,2 @@ };

* there is a linear algorithm. For now we have implementation for power-of-two bases only.
* @__NO_SIDE_EFFECTS__
*/

@@ -281,4 +293,3 @@ function radix2(bits: number, revPadding = false): Coder<Uint8Array, number[]> {

decode: (digits: number[]) => {
if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
throw new Error('radix2.decode input should be array of numbers');
anumArr('radix2.decode', digits);
return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));

@@ -290,7 +301,4 @@ },

type ArgumentTypes<F extends Function> = F extends (...args: infer A) => any ? A : never;
/**
* @__NO_SIDE_EFFECTS__
*/
function unsafeWrapper<T extends (...args: any) => any>(fn: T) {
if (typeof fn !== 'function') throw new Error('unsafeWrapper fn should be function');
afn(fn);
return function (...args: ArgumentTypes<T>): ReturnType<T> | void {

@@ -303,5 +311,2 @@ try {

/**
* @__NO_SIDE_EFFECTS__
*/
function checksum(

@@ -312,3 +317,3 @@ len: number,

assertNumber(len);
if (typeof fn !== 'function') throw new Error('checksum fn should be function');
afn(fn);
return {

@@ -342,2 +347,6 @@ encode(data: Uint8Array) {

// ---------------------
/**
* base16 encoding.
*/
export const base16: BytesCoder = /* @__PURE__ */ chain(

@@ -376,2 +385,8 @@ radix2(4),

);
/**
* base64 with padding. For no padding, use `base64nopad`.
* @example
* const b = base64.decode('A951'); // Uint8Array.from([ 3, 222, 117 ])
* base64.encode(b); // 'A951'
*/
export const base64: BytesCoder = /* @__PURE__ */ chain(

@@ -383,2 +398,5 @@ radix2(6),

);
/**
* base64 without padding.
*/
export const base64nopad: BytesCoder = /* @__PURE__ */ chain(

@@ -405,2 +423,6 @@ radix2(6),

/**
* Base58: base64 without characters +, /, 0, O, I, l.
* Quadratic (O(n^2)) - so, can't be used on large inputs.
*/
export const base58: BytesCoder = /* @__PURE__ */ genBase58(

@@ -416,7 +438,10 @@ '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'

// xmr ver is done in 8-byte blocks (which equals 11 chars in decoding). Last (non-full) block padded with '1' to size in XMR_BLOCK_LEN.
// Block encoding significantly reduces quadratic complexity of base58.
// Data len (index) -> encoded block len
const XMR_BLOCK_LEN = [0, 2, 3, 5, 6, 7, 9, 10, 11];
/**
* XMR version of base58.
* Done in 8-byte blocks (which equals 11 chars in decoding). Last (non-full) block padded with '1' to size in XMR_BLOCK_LEN.
* Block encoding significantly reduces quadratic complexity of base58.
*/
export const base58xmr: BytesCoder = {

@@ -451,3 +476,7 @@ encode(data: Uint8Array) {

);
// legacy export, bad name
/**
* Use `createBase58check` instead.
* @deprecated
*/
export const base58check = createBase58check;

@@ -473,5 +502,2 @@

const POLYMOD_GENERATORS = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
/**
* @__NO_SIDE_EFFECTS__
*/
function bech32Polymod(pre: number): number {

@@ -486,5 +512,2 @@ const b = pre >> 25;

/**
* @__NO_SIDE_EFFECTS__
*/
function bechChecksum(prefix: string, words: number[], encodingConst = 1): string {

@@ -503,3 +526,3 @@ const len = prefix.length;

chk ^= encodingConst;
return BECH_ALPHABET.encode(convertRadix2([chk % 2 ** 30], 30, 5, false));
return BECH_ALPHABET.encode(convertRadix2([chk % powers[30]!], 30, 5, false));
}

@@ -524,5 +547,2 @@

}
/**
* @__NO_SIDE_EFFECTS__
*/
function genBech32(encoding: 'bech32' | 'bech32m'): Bech32 {

@@ -540,9 +560,8 @@ const ENCODING_CONST = encoding === 'bech32' ? 1 : 0x2bc830a3;

): `${Lowercase<Prefix>}1${string}` {
if (typeof prefix !== 'string')
throw new Error(`bech32.encode prefix should be string, not ${typeof prefix}`);
if (words instanceof Uint8Array) words = Array.from(words);
if (!Array.isArray(words) || (words.length && typeof words[0] !== 'number'))
throw new Error(`bech32.encode words should be array of numbers, not ${typeof words}`);
if (prefix.length === 0) throw new TypeError(`Invalid prefix length ${prefix.length}`);
const actualLength = prefix.length + 7 + words.length;
astr('bech32.encode prefix', prefix);
if (isBytes(words)) words = Array.from(words);
anumArr('bech32.encode', words);
const plen = prefix.length;
if (plen === 0) throw new TypeError(`Invalid prefix length ${plen}`);
const actualLength = plen + 7 + words.length;
if (limit !== false && actualLength > limit)

@@ -561,6 +580,6 @@ throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`);

function decode(str: string, limit: number | false = 90): Bech32Decoded {
if (typeof str !== 'string')
throw new Error(`bech32.decode input should be string, not ${typeof str}`);
if (str.length < 8 || (limit !== false && str.length > limit))
throw new TypeError(`Wrong string length: ${str.length} (${str}). Expected (8..${limit})`);
astr('bech32.decode input', str);
const slen = str.length;
if (slen < 8 || (limit !== false && slen > limit))
throw new TypeError(`Wrong string length: ${slen} (${str}). Expected (8..${limit})`);
// don't allow mixed case

@@ -605,2 +624,5 @@ const lowered = str.toLowerCase();

/**
* Low-level bech32 operations. Operates on words.
*/
export const bech32: Bech32 = /* @__PURE__ */ genBech32('bech32');

@@ -612,2 +634,8 @@ export const bech32m: Bech32 = /* @__PURE__ */ genBech32('bech32m');

/**
* UTF-8-to-byte decoder. Uses built-in TextDecoder / TextEncoder.
* @example
* const b = utf8.decode("hey"); // => new Uint8Array([ 104, 101, 121 ])
* const str = utf8.encode(b); // "hey"
*/
export const utf8: BytesCoder = {

@@ -618,2 +646,8 @@ encode: (data) => new TextDecoder().decode(data),

/**
* hex string decoder.
* @example
* const b = hex.decode("0102ff"); // => new Uint8Array([ 1, 2, 255 ])
* const str = hex.encode(b); // "0102ff"
*/
export const hex: BytesCoder = /* @__PURE__ */ chain(

@@ -624,3 +658,3 @@ radix2(4),

normalize((s: string) => {
if (typeof s !== 'string' || s.length % 2)
if (typeof s !== 'string' || s.length % 2 !== 0)
throw new TypeError(`hex.decode: expected string, got ${typeof s} with length ${s.length}`);

@@ -627,0 +661,0 @@ return s.toLowerCase();

/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */
/**
* @__NO_SIDE_EFFECTS__
*/
export declare function assertNumber(n: number): void;

@@ -23,19 +20,11 @@ export interface Coder<F, T> {

};
/**
* @__NO_SIDE_EFFECTS__
*/
declare function chain<T extends Chain & AsChain<T>>(...args: T): Coder<Input<First<T>>, Output<Last<T>>>;
type Alphabet = string[] | string;
/**
* Encodes integer radix representation to array of strings using alphabet and back
* @__NO_SIDE_EFFECTS__
* Encodes integer radix representation to array of strings using alphabet and back.
* Could also be array of strings.
*/
declare function alphabet(alphabet: Alphabet): Coder<number[], string[]>;
/**
* @__NO_SIDE_EFFECTS__
*/
declare function alphabet(letters: string | string[]): Coder<number[], string[]>;
declare function join(separator?: string): Coder<string[], string>;
/**
* Pad strings array so it has integer number of bits
* @__NO_SIDE_EFFECTS__
*/

@@ -45,3 +34,2 @@ declare function padding(bits: number, chr?: string): Coder<string[], string[]>;

* Slow: O(n^2) time complexity
* @__NO_SIDE_EFFECTS__
*/

@@ -51,8 +39,4 @@ declare function convertRadix(data: number[], from: number, to: number): number[];

* Implemented with numbers, because BigInt is 5x slower
* @__NO_SIDE_EFFECTS__
*/
declare function convertRadix2(data: number[], from: number, to: number, padding: boolean): number[];
/**
* @__NO_SIDE_EFFECTS__
*/
declare function radix(num: number): Coder<Uint8Array, number[]>;

@@ -62,8 +46,4 @@ /**

* there is a linear algorithm. For now we have implementation for power-of-two bases only.
* @__NO_SIDE_EFFECTS__
*/
declare function radix2(bits: number, revPadding?: boolean): Coder<Uint8Array, number[]>;
/**
* @__NO_SIDE_EFFECTS__
*/
declare function checksum(len: number, fn: (data: Uint8Array) => Uint8Array): Coder<Uint8Array, Uint8Array>;

@@ -81,2 +61,5 @@ export declare const utils: {

};
/**
* base16 encoding.
*/
export declare const base16: BytesCoder;

@@ -88,11 +71,33 @@ export declare const base32: BytesCoder;

export declare const base32crockford: BytesCoder;
/**
* base64 with padding. For no padding, use `base64nopad`.
* @example
* const b = base64.decode('A951'); // Uint8Array.from([ 3, 222, 117 ])
* base64.encode(b); // 'A951'
*/
export declare const base64: BytesCoder;
/**
* base64 without padding.
*/
export declare const base64nopad: BytesCoder;
export declare const base64url: BytesCoder;
export declare const base64urlnopad: BytesCoder;
/**
* Base58: base64 without characters +, /, 0, O, I, l.
* Quadratic (O(n^2)) - so, can't be used on large inputs.
*/
export declare const base58: BytesCoder;
export declare const base58flickr: BytesCoder;
export declare const base58xrp: BytesCoder;
/**
* XMR version of base58.
* Done in 8-byte blocks (which equals 11 chars in decoding). Last (non-full) block padded with '1' to size in XMR_BLOCK_LEN.
* Block encoding significantly reduces quadratic complexity of base58.
*/
export declare const base58xmr: BytesCoder;
export declare const createBase58check: (sha256: (data: Uint8Array) => Uint8Array) => BytesCoder;
/**
* Use `createBase58check` instead.
* @deprecated
*/
export declare const base58check: (sha256: (data: Uint8Array) => Uint8Array) => BytesCoder;

@@ -118,5 +123,20 @@ export interface Bech32Decoded<Prefix extends string = string> {

}
/**
* Low-level bech32 operations. Operates on words.
*/
export declare const bech32: Bech32;
export declare const bech32m: Bech32;
/**
* UTF-8-to-byte decoder. Uses built-in TextDecoder / TextEncoder.
* @example
* const b = utf8.decode("hey"); // => new Uint8Array([ 104, 101, 121 ])
* const str = utf8.encode(b); // "hey"
*/
export declare const utf8: BytesCoder;
/**
* hex string decoder.
* @example
* const b = hex.decode("0102ff"); // => new Uint8Array([ 1, 2, 255 ])
* const str = hex.encode(b); // "0102ff"
*/
export declare const hex: BytesCoder;

@@ -123,0 +143,0 @@ declare const CODERS: {

/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */
// Utilities
/**
* @__NO_SIDE_EFFECTS__
*/
export function assertNumber(n) {

@@ -11,8 +8,36 @@ if (!Number.isSafeInteger(n))

function isBytes(a) {
return (a instanceof Uint8Array ||
(a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
}
/**
* @__NO_SIDE_EFFECTS__
*/
function isArrayOf(type, arr) {
if (!Array.isArray(arr))
return false;
if (arr.length === 0)
return true;
if (type === 'string')
return arr.every((item) => typeof item === 'string');
if (type === 'number')
return arr.every((item) => Number.isSafeInteger(item));
return false;
}
// no abytes: seems to have 10% slowdown. Why?!
function afn(input) {
if (typeof input !== 'function')
throw new Error('function expected');
return true;
}
function astr(label, input) {
if (typeof input !== 'string')
throw new Error(`${label}: string expected`);
return true;
}
function astrArr(label, input) {
if (!isArrayOf('string', input))
throw new Error(`${label}: array of strings expected`);
return true;
}
function anumArr(label, input) {
if (!isArrayOf('number', input))
throw new Error(`${label}: array of strings expected`);
return true;
}
function chain(...args) {

@@ -29,27 +54,31 @@ const id = (a) => a;

/**
* Encodes integer radix representation to array of strings using alphabet and back
* @__NO_SIDE_EFFECTS__
* Encodes integer radix representation to array of strings using alphabet and back.
* Could also be array of strings.
*/
function alphabet(alphabet) {
function alphabet(letters) {
// mapping 1 to "b"
const lettersA = typeof letters === 'string' ? letters.split('') : letters;
const len = lettersA.length;
astrArr('alphabet', lettersA);
// mapping "b" to 1
const indexes = new Map(lettersA.map((l, i) => [l, i]));
return {
encode: (digits) => {
if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
throw new Error('alphabet.encode input should be an array of numbers');
if (!Array.isArray(digits))
throw new Error('array expected');
return digits.map((i) => {
assertNumber(i);
if (i < 0 || i >= alphabet.length)
throw new Error(`Digit index outside alphabet: ${i} (alphabet: ${alphabet.length})`);
return alphabet[i];
if (!Number.isSafeInteger(i) || i < 0 || i >= len)
throw new Error(`alphabet.encode: digit index outside alphabet "${i}". Allowed: ${letters}`);
return lettersA[i];
});
},
decode: (input) => {
if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string'))
throw new Error('alphabet.decode input should be array of strings');
if (!Array.isArray(input))
throw new Error('array expected');
return input.map((letter) => {
if (typeof letter !== 'string')
throw new Error(`alphabet.decode: not string element=${letter}`);
const index = alphabet.indexOf(letter);
if (index === -1)
throw new Error(`Unknown letter: "${letter}". Allowed: ${alphabet}`);
return index;
astr('alphabet.decode', letter);
const i = indexes.get(letter);
if (i === undefined)
throw new Error(`Unknown letter: "${letter}". Allowed: ${letters}`);
return i;
});

@@ -59,20 +88,11 @@ },

}
/**
* @__NO_SIDE_EFFECTS__
*/
function join(separator = '') {
if (typeof separator !== 'string')
throw new Error('join separator should be string');
astr('join', separator);
return {
encode: (from) => {
if (!Array.isArray(from) || (from.length && typeof from[0] !== 'string'))
throw new Error('join.encode input should be array of strings');
for (let i of from)
if (typeof i !== 'string')
throw new Error(`join.encode: non-string input=${i}`);
astrArr('join.decode', from);
return from.join(separator);
},
decode: (to) => {
if (typeof to !== 'string')
throw new Error('join.decode input should be string');
astr('join.decode', to);
return to.split(separator);

@@ -84,15 +104,9 @@ },

* Pad strings array so it has integer number of bits
* @__NO_SIDE_EFFECTS__
*/
function padding(bits, chr = '=') {
assertNumber(bits);
if (typeof chr !== 'string')
throw new Error('padding chr should be string');
astr('padding', chr);
return {
encode(data) {
if (!Array.isArray(data) || (data.length && typeof data[0] !== 'string'))
throw new Error('padding.encode input should be array of strings');
for (let i of data)
if (typeof i !== 'string')
throw new Error(`padding.encode: non-string input=${i}`);
astrArr('padding.encode', data);
while ((data.length * bits) % 8)

@@ -103,13 +117,11 @@ data.push(chr);

decode(input) {
if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string'))
throw new Error('padding.encode input should be array of strings');
for (let i of input)
if (typeof i !== 'string')
throw new Error(`padding.decode: non-string input=${i}`);
astrArr('padding.decode', input);
let end = input.length;
if ((end * bits) % 8)
throw new Error('Invalid padding: string should have whole number of bytes');
throw new Error('padding: invalid, string should have whole number of bytes');
for (; end > 0 && input[end - 1] === chr; end--) {
if (!(((end - 1) * bits) % 8))
throw new Error('Invalid padding: string has too much padding');
const last = end - 1;
const byte = last * bits;
if (byte % 8 === 0)
throw new Error('padding: invalid, string has too much padding');
}

@@ -120,8 +132,4 @@ return input.slice(0, end);

}
/**
* @__NO_SIDE_EFFECTS__
*/
function normalize(fn) {
if (typeof fn !== 'function')
throw new Error('normalize fn should be function');
afn(fn);
return { encode: (from) => from, decode: (to) => fn(to) };

@@ -131,3 +139,2 @@ }

* Slow: O(n^2) time complexity
* @__NO_SIDE_EFFECTS__
*/

@@ -152,6 +159,7 @@ function convertRadix(data, from, to) {

});
const dlen = digits.length;
while (true) {
let carry = 0;
let done = true;
for (let i = pos; i < digits.length; i++) {
for (let i = pos; i < dlen; i++) {
const digit = digits[i];

@@ -164,4 +172,5 @@ const digitBase = from * carry + digit;

}
let div = digitBase / to;
carry = digitBase % to;
const rounded = Math.floor(digitBase / to);
const rounded = Math.floor(div);
digits[i] = rounded;

@@ -185,7 +194,12 @@ if (!Number.isSafeInteger(rounded) || rounded * to + carry !== digitBase)

}
const gcd = /* @__NO_SIDE_EFFECTS__ */ (a, b) => (!b ? a : gcd(b, a % b));
const gcd = (a, b) => (b === 0 ? a : gcd(b, a % b));
const radix2carry = /*@__NO_SIDE_EFFECTS__ */ (from, to) => from + (to - gcd(from, to));
const powers = /* @__PURE__ */ (() => {
let res = [];
for (let i = 0; i < 40; i++)
res.push(2 ** i);
return res;
})();
/**
* Implemented with numbers, because BigInt is 5x slower
* @__NO_SIDE_EFFECTS__
*/

@@ -204,7 +218,8 @@ function convertRadix2(data, from, to, padding) {

let pos = 0; // bitwise position in current element
const mask = 2 ** to - 1;
const max = powers[from];
const mask = powers[to] - 1;
const res = [];
for (const n of data) {
assertNumber(n);
if (n >= 2 ** from)
if (n >= max)
throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);

@@ -217,3 +232,6 @@ carry = (carry << from) | n;

res.push(((carry >> (pos - to)) & mask) >>> 0);
carry &= 2 ** pos - 1; // clean carry, otherwise it will cause overflow
const pow = powers[pos];
if (pow === undefined)
throw new Error('invalid carry');
carry &= pow - 1; // clean carry, otherwise it will cause overflow
}

@@ -223,3 +241,3 @@ carry = (carry << (to - pos)) & mask;

throw new Error('Excess padding');
if (!padding && carry)
if (!padding && carry > 0)
throw new Error(`Non-zero padding: ${carry}`);

@@ -230,7 +248,5 @@ if (padding && pos > 0)

}
/**
* @__NO_SIDE_EFFECTS__
*/
function radix(num) {
assertNumber(num);
const _256 = 2 ** 8;
return {

@@ -240,8 +256,7 @@ encode: (bytes) => {

throw new Error('radix.encode input should be Uint8Array');
return convertRadix(Array.from(bytes), 2 ** 8, num);
return convertRadix(Array.from(bytes), _256, num);
},
decode: (digits) => {
if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
throw new Error('radix.decode input should be array of numbers');
return Uint8Array.from(convertRadix(digits, num, 2 ** 8));
anumArr('radix.decode', digits);
return Uint8Array.from(convertRadix(digits, num, _256));
},

@@ -253,3 +268,2 @@ };

* there is a linear algorithm. For now we have implementation for power-of-two bases only.
* @__NO_SIDE_EFFECTS__
*/

@@ -269,4 +283,3 @@ function radix2(bits, revPadding = false) {

decode: (digits) => {
if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
throw new Error('radix2.decode input should be array of numbers');
anumArr('radix2.decode', digits);
return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));

@@ -276,8 +289,4 @@ },

}
/**
* @__NO_SIDE_EFFECTS__
*/
function unsafeWrapper(fn) {
if (typeof fn !== 'function')
throw new Error('unsafeWrapper fn should be function');
afn(fn);
return function (...args) {

@@ -290,9 +299,5 @@ try {

}
/**
* @__NO_SIDE_EFFECTS__
*/
function checksum(len, fn) {
assertNumber(len);
if (typeof fn !== 'function')
throw new Error('checksum fn should be function');
afn(fn);
return {

@@ -327,2 +332,5 @@ encode(data) {

// ---------------------
/**
* base16 encoding.
*/
export const base16 = /* @__PURE__ */ chain(radix2(4), alphabet('0123456789ABCDEF'), join(''));

@@ -334,3 +342,12 @@ export const base32 = /* @__PURE__ */ chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), padding(5), join(''));

export const base32crockford = /* @__PURE__ */ chain(radix2(5), alphabet('0123456789ABCDEFGHJKMNPQRSTVWXYZ'), join(''), normalize((s) => s.toUpperCase().replace(/O/g, '0').replace(/[IL]/g, '1')));
/**
* base64 with padding. For no padding, use `base64nopad`.
* @example
* const b = base64.decode('A951'); // Uint8Array.from([ 3, 222, 117 ])
* base64.encode(b); // 'A951'
*/
export const base64 = /* @__PURE__ */ chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), padding(6), join(''));
/**
* base64 without padding.
*/
export const base64nopad = /* @__PURE__ */ chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), join(''));

@@ -342,9 +359,16 @@ export const base64url = /* @__PURE__ */ chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), padding(6), join(''));

const genBase58 = (abc) => chain(radix(58), alphabet(abc), join(''));
/**
* Base58: base64 without characters +, /, 0, O, I, l.
* Quadratic (O(n^2)) - so, can't be used on large inputs.
*/
export const base58 = /* @__PURE__ */ genBase58('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
export const base58flickr = /* @__PURE__ */ genBase58('123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ');
export const base58xrp = /* @__PURE__ */ genBase58('rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz');
// xmr ver is done in 8-byte blocks (which equals 11 chars in decoding). Last (non-full) block padded with '1' to size in XMR_BLOCK_LEN.
// Block encoding significantly reduces quadratic complexity of base58.
// Data len (index) -> encoded block len
const XMR_BLOCK_LEN = [0, 2, 3, 5, 6, 7, 9, 10, 11];
/**
* XMR version of base58.
* Done in 8-byte blocks (which equals 11 chars in decoding). Last (non-full) block padded with '1' to size in XMR_BLOCK_LEN.
* Block encoding significantly reduces quadratic complexity of base58.
*/
export const base58xmr = {

@@ -375,9 +399,9 @@ encode(data) {

export const createBase58check = (sha256) => chain(checksum(4, (data) => sha256(sha256(data))), base58);
// legacy export, bad name
/**
* Use `createBase58check` instead.
* @deprecated
*/
export const base58check = createBase58check;
const BECH_ALPHABET = /* @__PURE__ */ chain(alphabet('qpzry9x8gf2tvdw0s3jn54khce6mua7l'), join(''));
const POLYMOD_GENERATORS = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
/**
* @__NO_SIDE_EFFECTS__
*/
function bech32Polymod(pre) {

@@ -392,5 +416,2 @@ const b = pre >> 25;

}
/**
* @__NO_SIDE_EFFECTS__
*/
function bechChecksum(prefix, words, encodingConst = 1) {

@@ -413,7 +434,4 @@ const len = prefix.length;

chk ^= encodingConst;
return BECH_ALPHABET.encode(convertRadix2([chk % 2 ** 30], 30, 5, false));
return BECH_ALPHABET.encode(convertRadix2([chk % powers[30]], 30, 5, false));
}
/**
* @__NO_SIDE_EFFECTS__
*/
function genBech32(encoding) {

@@ -426,11 +444,10 @@ const ENCODING_CONST = encoding === 'bech32' ? 1 : 0x2bc830a3;

function encode(prefix, words, limit = 90) {
if (typeof prefix !== 'string')
throw new Error(`bech32.encode prefix should be string, not ${typeof prefix}`);
if (words instanceof Uint8Array)
astr('bech32.encode prefix', prefix);
if (isBytes(words))
words = Array.from(words);
if (!Array.isArray(words) || (words.length && typeof words[0] !== 'number'))
throw new Error(`bech32.encode words should be array of numbers, not ${typeof words}`);
if (prefix.length === 0)
throw new TypeError(`Invalid prefix length ${prefix.length}`);
const actualLength = prefix.length + 7 + words.length;
anumArr('bech32.encode', words);
const plen = prefix.length;
if (plen === 0)
throw new TypeError(`Invalid prefix length ${plen}`);
const actualLength = plen + 7 + words.length;
if (limit !== false && actualLength > limit)

@@ -443,6 +460,6 @@ throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`);

function decode(str, limit = 90) {
if (typeof str !== 'string')
throw new Error(`bech32.decode input should be string, not ${typeof str}`);
if (str.length < 8 || (limit !== false && str.length > limit))
throw new TypeError(`Wrong string length: ${str.length} (${str}). Expected (8..${limit})`);
astr('bech32.decode input', str);
const slen = str.length;
if (slen < 8 || (limit !== false && slen > limit))
throw new TypeError(`Wrong string length: ${slen} (${str}). Expected (8..${limit})`);
// don't allow mixed case

@@ -484,4 +501,13 @@ const lowered = str.toLowerCase();

}
/**
* Low-level bech32 operations. Operates on words.
*/
export const bech32 = /* @__PURE__ */ genBech32('bech32');
export const bech32m = /* @__PURE__ */ genBech32('bech32m');
/**
* UTF-8-to-byte decoder. Uses built-in TextDecoder / TextEncoder.
* @example
* const b = utf8.decode("hey"); // => new Uint8Array([ 104, 101, 121 ])
* const str = utf8.encode(b); // "hey"
*/
export const utf8 = {

@@ -491,4 +517,10 @@ encode: (data) => new TextDecoder().decode(data),

};
/**
* hex string decoder.
* @example
* const b = hex.decode("0102ff"); // => new Uint8Array([ 1, 2, 255 ])
* const str = hex.encode(b); // "0102ff"
*/
export const hex = /* @__PURE__ */ chain(radix2(4), alphabet('0123456789abcdef'), join(''), normalize((s) => {
if (typeof s !== 'string' || s.length % 2)
if (typeof s !== 'string' || s.length % 2 !== 0)
throw new TypeError(`hex.decode: expected string, got ${typeof s} with length ${s.length}`);

@@ -495,0 +527,0 @@ return s.toLowerCase();

/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */
/**
* @__NO_SIDE_EFFECTS__
*/
export declare function assertNumber(n: number): void;

@@ -23,19 +20,11 @@ export interface Coder<F, T> {

};
/**
* @__NO_SIDE_EFFECTS__
*/
declare function chain<T extends Chain & AsChain<T>>(...args: T): Coder<Input<First<T>>, Output<Last<T>>>;
type Alphabet = string[] | string;
/**
* Encodes integer radix representation to array of strings using alphabet and back
* @__NO_SIDE_EFFECTS__
* Encodes integer radix representation to array of strings using alphabet and back.
* Could also be array of strings.
*/
declare function alphabet(alphabet: Alphabet): Coder<number[], string[]>;
/**
* @__NO_SIDE_EFFECTS__
*/
declare function alphabet(letters: string | string[]): Coder<number[], string[]>;
declare function join(separator?: string): Coder<string[], string>;
/**
* Pad strings array so it has integer number of bits
* @__NO_SIDE_EFFECTS__
*/

@@ -45,3 +34,2 @@ declare function padding(bits: number, chr?: string): Coder<string[], string[]>;

* Slow: O(n^2) time complexity
* @__NO_SIDE_EFFECTS__
*/

@@ -51,8 +39,4 @@ declare function convertRadix(data: number[], from: number, to: number): number[];

* Implemented with numbers, because BigInt is 5x slower
* @__NO_SIDE_EFFECTS__
*/
declare function convertRadix2(data: number[], from: number, to: number, padding: boolean): number[];
/**
* @__NO_SIDE_EFFECTS__
*/
declare function radix(num: number): Coder<Uint8Array, number[]>;

@@ -62,8 +46,4 @@ /**

* there is a linear algorithm. For now we have implementation for power-of-two bases only.
* @__NO_SIDE_EFFECTS__
*/
declare function radix2(bits: number, revPadding?: boolean): Coder<Uint8Array, number[]>;
/**
* @__NO_SIDE_EFFECTS__
*/
declare function checksum(len: number, fn: (data: Uint8Array) => Uint8Array): Coder<Uint8Array, Uint8Array>;

@@ -81,2 +61,5 @@ export declare const utils: {

};
/**
* base16 encoding.
*/
export declare const base16: BytesCoder;

@@ -88,11 +71,33 @@ export declare const base32: BytesCoder;

export declare const base32crockford: BytesCoder;
/**
* base64 with padding. For no padding, use `base64nopad`.
* @example
* const b = base64.decode('A951'); // Uint8Array.from([ 3, 222, 117 ])
* base64.encode(b); // 'A951'
*/
export declare const base64: BytesCoder;
/**
* base64 without padding.
*/
export declare const base64nopad: BytesCoder;
export declare const base64url: BytesCoder;
export declare const base64urlnopad: BytesCoder;
/**
* Base58: base64 without characters +, /, 0, O, I, l.
* Quadratic (O(n^2)) - so, can't be used on large inputs.
*/
export declare const base58: BytesCoder;
export declare const base58flickr: BytesCoder;
export declare const base58xrp: BytesCoder;
/**
* XMR version of base58.
* Done in 8-byte blocks (which equals 11 chars in decoding). Last (non-full) block padded with '1' to size in XMR_BLOCK_LEN.
* Block encoding significantly reduces quadratic complexity of base58.
*/
export declare const base58xmr: BytesCoder;
export declare const createBase58check: (sha256: (data: Uint8Array) => Uint8Array) => BytesCoder;
/**
* Use `createBase58check` instead.
* @deprecated
*/
export declare const base58check: (sha256: (data: Uint8Array) => Uint8Array) => BytesCoder;

@@ -118,5 +123,20 @@ export interface Bech32Decoded<Prefix extends string = string> {

}
/**
* Low-level bech32 operations. Operates on words.
*/
export declare const bech32: Bech32;
export declare const bech32m: Bech32;
/**
* UTF-8-to-byte decoder. Uses built-in TextDecoder / TextEncoder.
* @example
* const b = utf8.decode("hey"); // => new Uint8Array([ 104, 101, 121 ])
* const str = utf8.encode(b); // "hey"
*/
export declare const utf8: BytesCoder;
/**
* hex string decoder.
* @example
* const b = hex.decode("0102ff"); // => new Uint8Array([ 1, 2, 255 ])
* const str = hex.encode(b); // "0102ff"
*/
export declare const hex: BytesCoder;

@@ -123,0 +143,0 @@ declare const CODERS: {

@@ -7,5 +7,2 @@ "use strict";

// Utilities
/**
* @__NO_SIDE_EFFECTS__
*/
function assertNumber(n) {

@@ -16,8 +13,36 @@ if (!Number.isSafeInteger(n))

function isBytes(a) {
return (a instanceof Uint8Array ||
(a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
}
/**
* @__NO_SIDE_EFFECTS__
*/
function isArrayOf(type, arr) {
if (!Array.isArray(arr))
return false;
if (arr.length === 0)
return true;
if (type === 'string')
return arr.every((item) => typeof item === 'string');
if (type === 'number')
return arr.every((item) => Number.isSafeInteger(item));
return false;
}
// no abytes: seems to have 10% slowdown. Why?!
function afn(input) {
if (typeof input !== 'function')
throw new Error('function expected');
return true;
}
function astr(label, input) {
if (typeof input !== 'string')
throw new Error(`${label}: string expected`);
return true;
}
function astrArr(label, input) {
if (!isArrayOf('string', input))
throw new Error(`${label}: array of strings expected`);
return true;
}
function anumArr(label, input) {
if (!isArrayOf('number', input))
throw new Error(`${label}: array of strings expected`);
return true;
}
function chain(...args) {

@@ -34,27 +59,31 @@ const id = (a) => a;

/**
* Encodes integer radix representation to array of strings using alphabet and back
* @__NO_SIDE_EFFECTS__
* Encodes integer radix representation to array of strings using alphabet and back.
* Could also be array of strings.
*/
function alphabet(alphabet) {
function alphabet(letters) {
// mapping 1 to "b"
const lettersA = typeof letters === 'string' ? letters.split('') : letters;
const len = lettersA.length;
astrArr('alphabet', lettersA);
// mapping "b" to 1
const indexes = new Map(lettersA.map((l, i) => [l, i]));
return {
encode: (digits) => {
if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
throw new Error('alphabet.encode input should be an array of numbers');
if (!Array.isArray(digits))
throw new Error('array expected');
return digits.map((i) => {
assertNumber(i);
if (i < 0 || i >= alphabet.length)
throw new Error(`Digit index outside alphabet: ${i} (alphabet: ${alphabet.length})`);
return alphabet[i];
if (!Number.isSafeInteger(i) || i < 0 || i >= len)
throw new Error(`alphabet.encode: digit index outside alphabet "${i}". Allowed: ${letters}`);
return lettersA[i];
});
},
decode: (input) => {
if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string'))
throw new Error('alphabet.decode input should be array of strings');
if (!Array.isArray(input))
throw new Error('array expected');
return input.map((letter) => {
if (typeof letter !== 'string')
throw new Error(`alphabet.decode: not string element=${letter}`);
const index = alphabet.indexOf(letter);
if (index === -1)
throw new Error(`Unknown letter: "${letter}". Allowed: ${alphabet}`);
return index;
astr('alphabet.decode', letter);
const i = indexes.get(letter);
if (i === undefined)
throw new Error(`Unknown letter: "${letter}". Allowed: ${letters}`);
return i;
});

@@ -64,20 +93,11 @@ },

}
/**
* @__NO_SIDE_EFFECTS__
*/
function join(separator = '') {
if (typeof separator !== 'string')
throw new Error('join separator should be string');
astr('join', separator);
return {
encode: (from) => {
if (!Array.isArray(from) || (from.length && typeof from[0] !== 'string'))
throw new Error('join.encode input should be array of strings');
for (let i of from)
if (typeof i !== 'string')
throw new Error(`join.encode: non-string input=${i}`);
astrArr('join.decode', from);
return from.join(separator);
},
decode: (to) => {
if (typeof to !== 'string')
throw new Error('join.decode input should be string');
astr('join.decode', to);
return to.split(separator);

@@ -89,15 +109,9 @@ },

* Pad strings array so it has integer number of bits
* @__NO_SIDE_EFFECTS__
*/
function padding(bits, chr = '=') {
assertNumber(bits);
if (typeof chr !== 'string')
throw new Error('padding chr should be string');
astr('padding', chr);
return {
encode(data) {
if (!Array.isArray(data) || (data.length && typeof data[0] !== 'string'))
throw new Error('padding.encode input should be array of strings');
for (let i of data)
if (typeof i !== 'string')
throw new Error(`padding.encode: non-string input=${i}`);
astrArr('padding.encode', data);
while ((data.length * bits) % 8)

@@ -108,13 +122,11 @@ data.push(chr);

decode(input) {
if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string'))
throw new Error('padding.encode input should be array of strings');
for (let i of input)
if (typeof i !== 'string')
throw new Error(`padding.decode: non-string input=${i}`);
astrArr('padding.decode', input);
let end = input.length;
if ((end * bits) % 8)
throw new Error('Invalid padding: string should have whole number of bytes');
throw new Error('padding: invalid, string should have whole number of bytes');
for (; end > 0 && input[end - 1] === chr; end--) {
if (!(((end - 1) * bits) % 8))
throw new Error('Invalid padding: string has too much padding');
const last = end - 1;
const byte = last * bits;
if (byte % 8 === 0)
throw new Error('padding: invalid, string has too much padding');
}

@@ -125,8 +137,4 @@ return input.slice(0, end);

}
/**
* @__NO_SIDE_EFFECTS__
*/
function normalize(fn) {
if (typeof fn !== 'function')
throw new Error('normalize fn should be function');
afn(fn);
return { encode: (from) => from, decode: (to) => fn(to) };

@@ -136,3 +144,2 @@ }

* Slow: O(n^2) time complexity
* @__NO_SIDE_EFFECTS__
*/

@@ -157,6 +164,7 @@ function convertRadix(data, from, to) {

});
const dlen = digits.length;
while (true) {
let carry = 0;
let done = true;
for (let i = pos; i < digits.length; i++) {
for (let i = pos; i < dlen; i++) {
const digit = digits[i];

@@ -169,4 +177,5 @@ const digitBase = from * carry + digit;

}
let div = digitBase / to;
carry = digitBase % to;
const rounded = Math.floor(digitBase / to);
const rounded = Math.floor(div);
digits[i] = rounded;

@@ -190,7 +199,12 @@ if (!Number.isSafeInteger(rounded) || rounded * to + carry !== digitBase)

}
const gcd = /* @__NO_SIDE_EFFECTS__ */ (a, b) => (!b ? a : gcd(b, a % b));
const gcd = (a, b) => (b === 0 ? a : gcd(b, a % b));
const radix2carry = /*@__NO_SIDE_EFFECTS__ */ (from, to) => from + (to - gcd(from, to));
const powers = /* @__PURE__ */ (() => {
let res = [];
for (let i = 0; i < 40; i++)
res.push(2 ** i);
return res;
})();
/**
* Implemented with numbers, because BigInt is 5x slower
* @__NO_SIDE_EFFECTS__
*/

@@ -209,7 +223,8 @@ function convertRadix2(data, from, to, padding) {

let pos = 0; // bitwise position in current element
const mask = 2 ** to - 1;
const max = powers[from];
const mask = powers[to] - 1;
const res = [];
for (const n of data) {
assertNumber(n);
if (n >= 2 ** from)
if (n >= max)
throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);

@@ -222,3 +237,6 @@ carry = (carry << from) | n;

res.push(((carry >> (pos - to)) & mask) >>> 0);
carry &= 2 ** pos - 1; // clean carry, otherwise it will cause overflow
const pow = powers[pos];
if (pow === undefined)
throw new Error('invalid carry');
carry &= pow - 1; // clean carry, otherwise it will cause overflow
}

@@ -228,3 +246,3 @@ carry = (carry << (to - pos)) & mask;

throw new Error('Excess padding');
if (!padding && carry)
if (!padding && carry > 0)
throw new Error(`Non-zero padding: ${carry}`);

@@ -235,7 +253,5 @@ if (padding && pos > 0)

}
/**
* @__NO_SIDE_EFFECTS__
*/
function radix(num) {
assertNumber(num);
const _256 = 2 ** 8;
return {

@@ -245,8 +261,7 @@ encode: (bytes) => {

throw new Error('radix.encode input should be Uint8Array');
return convertRadix(Array.from(bytes), 2 ** 8, num);
return convertRadix(Array.from(bytes), _256, num);
},
decode: (digits) => {
if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
throw new Error('radix.decode input should be array of numbers');
return Uint8Array.from(convertRadix(digits, num, 2 ** 8));
anumArr('radix.decode', digits);
return Uint8Array.from(convertRadix(digits, num, _256));
},

@@ -258,3 +273,2 @@ };

* there is a linear algorithm. For now we have implementation for power-of-two bases only.
* @__NO_SIDE_EFFECTS__
*/

@@ -274,4 +288,3 @@ function radix2(bits, revPadding = false) {

decode: (digits) => {
if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
throw new Error('radix2.decode input should be array of numbers');
anumArr('radix2.decode', digits);
return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));

@@ -281,8 +294,4 @@ },

}
/**
* @__NO_SIDE_EFFECTS__
*/
function unsafeWrapper(fn) {
if (typeof fn !== 'function')
throw new Error('unsafeWrapper fn should be function');
afn(fn);
return function (...args) {

@@ -295,9 +304,5 @@ try {

}
/**
* @__NO_SIDE_EFFECTS__
*/
function checksum(len, fn) {
assertNumber(len);
if (typeof fn !== 'function')
throw new Error('checksum fn should be function');
afn(fn);
return {

@@ -332,2 +337,5 @@ encode(data) {

// ---------------------
/**
* base16 encoding.
*/
exports.base16 = chain(radix2(4), alphabet('0123456789ABCDEF'), join(''));

@@ -339,3 +347,12 @@ exports.base32 = chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), padding(5), join(''));

exports.base32crockford = chain(radix2(5), alphabet('0123456789ABCDEFGHJKMNPQRSTVWXYZ'), join(''), normalize((s) => s.toUpperCase().replace(/O/g, '0').replace(/[IL]/g, '1')));
/**
* base64 with padding. For no padding, use `base64nopad`.
* @example
* const b = base64.decode('A951'); // Uint8Array.from([ 3, 222, 117 ])
* base64.encode(b); // 'A951'
*/
exports.base64 = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), padding(6), join(''));
/**
* base64 without padding.
*/
exports.base64nopad = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), join(''));

@@ -347,9 +364,16 @@ exports.base64url = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), padding(6), join(''));

const genBase58 = (abc) => chain(radix(58), alphabet(abc), join(''));
/**
* Base58: base64 without characters +, /, 0, O, I, l.
* Quadratic (O(n^2)) - so, can't be used on large inputs.
*/
exports.base58 = genBase58('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
exports.base58flickr = genBase58('123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ');
exports.base58xrp = genBase58('rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz');
// xmr ver is done in 8-byte blocks (which equals 11 chars in decoding). Last (non-full) block padded with '1' to size in XMR_BLOCK_LEN.
// Block encoding significantly reduces quadratic complexity of base58.
// Data len (index) -> encoded block len
const XMR_BLOCK_LEN = [0, 2, 3, 5, 6, 7, 9, 10, 11];
/**
* XMR version of base58.
* Done in 8-byte blocks (which equals 11 chars in decoding). Last (non-full) block padded with '1' to size in XMR_BLOCK_LEN.
* Block encoding significantly reduces quadratic complexity of base58.
*/
exports.base58xmr = {

@@ -381,9 +405,9 @@ encode(data) {

exports.createBase58check = createBase58check;
// legacy export, bad name
/**
* Use `createBase58check` instead.
* @deprecated
*/
exports.base58check = exports.createBase58check;
const BECH_ALPHABET = /* @__PURE__ */ chain(alphabet('qpzry9x8gf2tvdw0s3jn54khce6mua7l'), join(''));
const POLYMOD_GENERATORS = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
/**
* @__NO_SIDE_EFFECTS__
*/
function bech32Polymod(pre) {

@@ -398,5 +422,2 @@ const b = pre >> 25;

}
/**
* @__NO_SIDE_EFFECTS__
*/
function bechChecksum(prefix, words, encodingConst = 1) {

@@ -419,7 +440,4 @@ const len = prefix.length;

chk ^= encodingConst;
return BECH_ALPHABET.encode(convertRadix2([chk % 2 ** 30], 30, 5, false));
return BECH_ALPHABET.encode(convertRadix2([chk % powers[30]], 30, 5, false));
}
/**
* @__NO_SIDE_EFFECTS__
*/
function genBech32(encoding) {

@@ -432,11 +450,10 @@ const ENCODING_CONST = encoding === 'bech32' ? 1 : 0x2bc830a3;

function encode(prefix, words, limit = 90) {
if (typeof prefix !== 'string')
throw new Error(`bech32.encode prefix should be string, not ${typeof prefix}`);
if (words instanceof Uint8Array)
astr('bech32.encode prefix', prefix);
if (isBytes(words))
words = Array.from(words);
if (!Array.isArray(words) || (words.length && typeof words[0] !== 'number'))
throw new Error(`bech32.encode words should be array of numbers, not ${typeof words}`);
if (prefix.length === 0)
throw new TypeError(`Invalid prefix length ${prefix.length}`);
const actualLength = prefix.length + 7 + words.length;
anumArr('bech32.encode', words);
const plen = prefix.length;
if (plen === 0)
throw new TypeError(`Invalid prefix length ${plen}`);
const actualLength = plen + 7 + words.length;
if (limit !== false && actualLength > limit)

@@ -449,6 +466,6 @@ throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`);

function decode(str, limit = 90) {
if (typeof str !== 'string')
throw new Error(`bech32.decode input should be string, not ${typeof str}`);
if (str.length < 8 || (limit !== false && str.length > limit))
throw new TypeError(`Wrong string length: ${str.length} (${str}). Expected (8..${limit})`);
astr('bech32.decode input', str);
const slen = str.length;
if (slen < 8 || (limit !== false && slen > limit))
throw new TypeError(`Wrong string length: ${slen} (${str}). Expected (8..${limit})`);
// don't allow mixed case

@@ -490,4 +507,13 @@ const lowered = str.toLowerCase();

}
/**
* Low-level bech32 operations. Operates on words.
*/
exports.bech32 = genBech32('bech32');
exports.bech32m = genBech32('bech32m');
/**
* UTF-8-to-byte decoder. Uses built-in TextDecoder / TextEncoder.
* @example
* const b = utf8.decode("hey"); // => new Uint8Array([ 104, 101, 121 ])
* const str = utf8.encode(b); // "hey"
*/
exports.utf8 = {

@@ -497,4 +523,10 @@ encode: (data) => new TextDecoder().decode(data),

};
/**
* hex string decoder.
* @example
* const b = hex.decode("0102ff"); // => new Uint8Array([ 1, 2, 255 ])
* const str = hex.encode(b); // "0102ff"
*/
exports.hex = chain(radix2(4), alphabet('0123456789abcdef'), join(''), normalize((s) => {
if (typeof s !== 'string' || s.length % 2)
if (typeof s !== 'string' || s.length % 2 !== 0)
throw new TypeError(`hex.decode: expected string, got ${typeof s} with length ${s.length}`);

@@ -501,0 +533,0 @@ return s.toLowerCase();

{
"name": "@scure/base",
"version": "1.1.9",
"version": "1.2.0",
"description": "Secure, audited & 0-dep implementation of base64, bech32, base58, base32 & base16",

@@ -44,2 +44,3 @@ "files": [

"@paulmillr/jsbt": "0.2.1",
"fast-check": "3.0.0",
"micro-should": "0.4.0",

@@ -46,0 +47,0 @@ "prettier": "3.3.2",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc