@uncefact/untp-utils 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # @uncefact/untp-utils
2
+
3
+ Shared utility primitives for UNTP packages and consumers.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ yarn add @uncefact/untp-utils
9
+ ```
10
+
11
+ ## MultibaseDigest
12
+
13
+ Encode, decode and verify multibase-encoded multihashes.
14
+
15
+ ```ts
16
+ import { MultibaseDigest } from '@uncefact/untp-utils';
17
+
18
+ // Hash some data, wrap as a multihash, encode as a multibase string.
19
+ const digest = await MultibaseDigest.fromData(new TextEncoder().encode('hello'), {
20
+ algorithm: 'sha2-256',
21
+ base: 'base58btc',
22
+ });
23
+
24
+ digest.toString(); // e.g. "zQmYwAPJzv5..." (base58btc)
25
+ digest.toString('base64'); // e.g. "mEiBL..." (re-encoded, no rehash)
26
+
27
+ // Parse a multibase string. Algorithm and encoding are read from the string.
28
+ const parsed = MultibaseDigest.fromString(digest.toString());
29
+ parsed.algorithm; // "sha2-256"
30
+ parsed.base; // "base58btc"
31
+
32
+ // Verify against original data.
33
+ await parsed.verify(new TextEncoder().encode('hello')); // true | false
34
+ ```
35
+
36
+ Supported algorithms: `sha2-256`, `sha2-512`.
37
+
38
+ Supported multibase encodings: `base58btc`, `base64`.
@@ -0,0 +1 @@
1
+ export * from './multibase-digest/index.js';
package/build/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from './multibase-digest/index.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { MultibaseDigest } from './multibase-digest.js';
2
+ export type { HashAlgorithm, MultibaseEncoding, MultibaseDigestOptions } from './multibase-digest.js';
@@ -0,0 +1,2 @@
1
+ export { MultibaseDigest } from './multibase-digest.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/multibase-digest/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Hash algorithms accepted by {@link MultibaseDigest}. Recovered from the
3
+ * multihash prefix on decode, supplied by the caller on encode.
4
+ */
5
+ export type HashAlgorithm = 'sha2-256' | 'sha2-512';
6
+ /**
7
+ * Multibase encodings accepted by {@link MultibaseDigest}. Recovered from the
8
+ * single-character prefix on a multibase string (`z` for base58btc, `m` for
9
+ * base64), supplied by the caller on encode.
10
+ */
11
+ export type MultibaseEncoding = 'base58btc' | 'base64';
12
+ /**
13
+ * Algorithm and base selection for the encode-side {@link MultibaseDigest}
14
+ * constructors ({@link MultibaseDigest.fromData}, {@link MultibaseDigest.fromDigest}).
15
+ * Decode-side construction reads both from the input string and takes no options.
16
+ */
17
+ export interface MultibaseDigestOptions {
18
+ algorithm: HashAlgorithm;
19
+ base: MultibaseEncoding;
20
+ }
21
+ /**
22
+ * Immutable value object representing a multibase-encoded multihash: a hash
23
+ * digest wrapped with its algorithm code (multihash) and paired with a chosen
24
+ * text encoding (multibase). Multihash and multibase are two separate
25
+ * specifications: multihash self-describes which hash algorithm produced the
26
+ * bytes; multibase self-describes which text encoding was used to render those
27
+ * bytes as a string. Instances are only obtainable through the static
28
+ * constructors, which validate inputs against the allow-lists.
29
+ *
30
+ * Two instances are equal when their underlying multihash bytes match. The
31
+ * chosen `base` is presentational and does not affect identity, so the same
32
+ * digest re-encoded under a different base compares equal.
33
+ *
34
+ * @see https://github.com/multiformats/multihash Multihash specification
35
+ * @see https://github.com/multiformats/multibase Multibase specification
36
+ */
37
+ export declare class MultibaseDigest {
38
+ /** Hash algorithm used to produce {@link digest}. */
39
+ readonly algorithm: HashAlgorithm;
40
+ /** Multibase encoding used by {@link toString} when no override is supplied. */
41
+ readonly base: MultibaseEncoding;
42
+ /** Raw hash bytes (no multihash prefix). Length matches {@link algorithm}. */
43
+ readonly digest: Uint8Array;
44
+ /** Multihash bytes (varint code + varint length + {@link digest}). */
45
+ readonly multihash: Uint8Array;
46
+ private constructor();
47
+ /**
48
+ * Hashes `data` with the requested algorithm, wraps it as a multihash, and
49
+ * tags it with the requested multibase encoding for serialisation.
50
+ *
51
+ * @throws If `algorithm` or `base` is not in the allow-list.
52
+ */
53
+ static fromData(data: Uint8Array, opts: MultibaseDigestOptions): Promise<MultibaseDigest>;
54
+ /**
55
+ * Wraps an already-computed raw `digest` (the bytes a hash function produces,
56
+ * no multihash prefix) and tags it with the requested multibase encoding. The
57
+ * caller asserts the algorithm; the byte length must match its expected
58
+ * digest size.
59
+ *
60
+ * @throws If `algorithm` or `base` is not in the allow-list, or if `digest.length`
61
+ * does not match the expected size for `algorithm`.
62
+ */
63
+ static fromDigest(digest: Uint8Array, opts: MultibaseDigestOptions): MultibaseDigest;
64
+ /**
65
+ * Parses a multibase string into a {@link MultibaseDigest}. The algorithm and
66
+ * multibase encoding are both recovered from the string itself: the leading
67
+ * character names the multibase, and the multihash prefix bytes name the
68
+ * algorithm.
69
+ *
70
+ * Decode and multihash-parse errors are rethrown with `{ cause }` so the
71
+ * underlying multiformats error is preserved for debugging.
72
+ *
73
+ * @throws If `encoded` is empty, the multibase prefix is unknown, the body
74
+ * cannot be decoded, the multihash bytes are malformed, or the multihash
75
+ * algorithm code is not in the allow-list.
76
+ */
77
+ static fromString(encoded: string): MultibaseDigest;
78
+ /**
79
+ * Returns the multibase-encoded multihash as a string. When called without
80
+ * arguments, uses {@link base}; pass a supported encoding to re-encode without
81
+ * rehashing.
82
+ *
83
+ * @throws If `base` is not in the allow-list.
84
+ */
85
+ toString(base?: MultibaseEncoding): string;
86
+ /**
87
+ * Returns `true` when `other` has the same algorithm and identical multihash
88
+ * bytes. The base is presentational and does not participate in equality, so
89
+ * the same digest encoded under different bases compares equal.
90
+ */
91
+ equals(other: MultibaseDigest): boolean;
92
+ /**
93
+ * Re-hashes `data` with this digest's own algorithm and compares against the
94
+ * stored digest. Returns `false` only on a genuine digest mismatch; throws if
95
+ * `data` cannot be hashed (e.g. invalid input type). Callers must not wrap
96
+ * this in `.catch(() => false)`, which would mask real failures as mismatches.
97
+ */
98
+ verify(data: Uint8Array): Promise<boolean>;
99
+ }
@@ -0,0 +1,188 @@
1
+ import * as Digest from 'multiformats/hashes/digest';
2
+ import { sha256, sha512 } from 'multiformats/hashes/sha2';
3
+ import { base58btc } from 'multiformats/bases/base58';
4
+ import { base64 } from 'multiformats/bases/base64';
5
+ const HASHERS = {
6
+ 'sha2-256': sha256,
7
+ 'sha2-512': sha512,
8
+ };
9
+ const HASH_CODE_TO_ALGORITHM = {
10
+ [sha256.code]: 'sha2-256',
11
+ [sha512.code]: 'sha2-512',
12
+ };
13
+ const DIGEST_LENGTHS = {
14
+ 'sha2-256': 32,
15
+ 'sha2-512': 64,
16
+ };
17
+ const BASES = {
18
+ base58btc,
19
+ base64,
20
+ };
21
+ const BASE_PREFIX_TO_ENCODING = {
22
+ [base58btc.prefix]: 'base58btc',
23
+ [base64.prefix]: 'base64',
24
+ };
25
+ function bytesEqual(a, b) {
26
+ if (a.length !== b.length)
27
+ return false;
28
+ for (let i = 0; i < a.length; i += 1) {
29
+ if (a[i] !== b[i])
30
+ return false;
31
+ }
32
+ return true;
33
+ }
34
+ function errorMessage(err) {
35
+ return err instanceof Error ? err.message : String(err);
36
+ }
37
+ function assertSupportedAlgorithm(algorithm) {
38
+ if (!HASHERS[algorithm]) {
39
+ throw new Error(`Unsupported hash algorithm: "${algorithm}"`);
40
+ }
41
+ }
42
+ function assertSupportedBase(base) {
43
+ if (!BASES[base]) {
44
+ throw new Error(`Unsupported multibase encoding: "${base}"`);
45
+ }
46
+ }
47
+ /**
48
+ * Immutable value object representing a multibase-encoded multihash: a hash
49
+ * digest wrapped with its algorithm code (multihash) and paired with a chosen
50
+ * text encoding (multibase). Multihash and multibase are two separate
51
+ * specifications: multihash self-describes which hash algorithm produced the
52
+ * bytes; multibase self-describes which text encoding was used to render those
53
+ * bytes as a string. Instances are only obtainable through the static
54
+ * constructors, which validate inputs against the allow-lists.
55
+ *
56
+ * Two instances are equal when their underlying multihash bytes match. The
57
+ * chosen `base` is presentational and does not affect identity, so the same
58
+ * digest re-encoded under a different base compares equal.
59
+ *
60
+ * @see https://github.com/multiformats/multihash Multihash specification
61
+ * @see https://github.com/multiformats/multibase Multibase specification
62
+ */
63
+ export class MultibaseDigest {
64
+ /** Hash algorithm used to produce {@link digest}. */
65
+ algorithm;
66
+ /** Multibase encoding used by {@link toString} when no override is supplied. */
67
+ base;
68
+ /** Raw hash bytes (no multihash prefix). Length matches {@link algorithm}. */
69
+ digest;
70
+ /** Multihash bytes (varint code + varint length + {@link digest}). */
71
+ multihash;
72
+ constructor(algorithm, base, digest, multihash) {
73
+ this.algorithm = algorithm;
74
+ this.base = base;
75
+ this.digest = digest;
76
+ this.multihash = multihash;
77
+ }
78
+ /**
79
+ * Hashes `data` with the requested algorithm, wraps it as a multihash, and
80
+ * tags it with the requested multibase encoding for serialisation.
81
+ *
82
+ * @throws If `algorithm` or `base` is not in the allow-list.
83
+ */
84
+ static async fromData(data, opts) {
85
+ assertSupportedAlgorithm(opts.algorithm);
86
+ assertSupportedBase(opts.base);
87
+ const hasher = HASHERS[opts.algorithm];
88
+ const mh = await hasher.digest(data);
89
+ return new MultibaseDigest(opts.algorithm, opts.base, mh.digest, mh.bytes);
90
+ }
91
+ /**
92
+ * Wraps an already-computed raw `digest` (the bytes a hash function produces,
93
+ * no multihash prefix) and tags it with the requested multibase encoding. The
94
+ * caller asserts the algorithm; the byte length must match its expected
95
+ * digest size.
96
+ *
97
+ * @throws If `algorithm` or `base` is not in the allow-list, or if `digest.length`
98
+ * does not match the expected size for `algorithm`.
99
+ */
100
+ static fromDigest(digest, opts) {
101
+ assertSupportedAlgorithm(opts.algorithm);
102
+ assertSupportedBase(opts.base);
103
+ const expectedLength = DIGEST_LENGTHS[opts.algorithm];
104
+ if (digest.length !== expectedLength) {
105
+ throw new Error(`Digest length ${digest.length} does not match "${opts.algorithm}" (expected ${expectedLength})`);
106
+ }
107
+ const hasher = HASHERS[opts.algorithm];
108
+ const mh = Digest.create(hasher.code, digest);
109
+ return new MultibaseDigest(opts.algorithm, opts.base, mh.digest, mh.bytes);
110
+ }
111
+ /**
112
+ * Parses a multibase string into a {@link MultibaseDigest}. The algorithm and
113
+ * multibase encoding are both recovered from the string itself: the leading
114
+ * character names the multibase, and the multihash prefix bytes name the
115
+ * algorithm.
116
+ *
117
+ * Decode and multihash-parse errors are rethrown with `{ cause }` so the
118
+ * underlying multiformats error is preserved for debugging.
119
+ *
120
+ * @throws If `encoded` is empty, the multibase prefix is unknown, the body
121
+ * cannot be decoded, the multihash bytes are malformed, or the multihash
122
+ * algorithm code is not in the allow-list.
123
+ */
124
+ static fromString(encoded) {
125
+ if (typeof encoded !== 'string' || encoded.length === 0) {
126
+ throw new Error('Multibase string must be a non-empty string');
127
+ }
128
+ const prefix = encoded[0];
129
+ const base = BASE_PREFIX_TO_ENCODING[prefix];
130
+ if (!base) {
131
+ throw new Error(`Unsupported multibase prefix: "${prefix}"`);
132
+ }
133
+ const codec = BASES[base];
134
+ let mhBytes;
135
+ try {
136
+ mhBytes = codec.decoder.decode(encoded);
137
+ }
138
+ catch (err) {
139
+ throw new Error(`Failed to decode multibase string: ${errorMessage(err)}`, { cause: err });
140
+ }
141
+ let mh;
142
+ try {
143
+ mh = Digest.decode(mhBytes);
144
+ }
145
+ catch (err) {
146
+ throw new Error(`Failed to parse multihash: ${errorMessage(err)}`, { cause: err });
147
+ }
148
+ const algorithm = HASH_CODE_TO_ALGORITHM[mh.code];
149
+ if (!algorithm) {
150
+ throw new Error(`Unsupported multihash algorithm code: 0x${mh.code.toString(16)}`);
151
+ }
152
+ return new MultibaseDigest(algorithm, base, mh.digest, mh.bytes);
153
+ }
154
+ /**
155
+ * Returns the multibase-encoded multihash as a string. When called without
156
+ * arguments, uses {@link base}; pass a supported encoding to re-encode without
157
+ * rehashing.
158
+ *
159
+ * @throws If `base` is not in the allow-list.
160
+ */
161
+ toString(base) {
162
+ const target = base ?? this.base;
163
+ assertSupportedBase(target);
164
+ return BASES[target].encoder.encode(this.multihash);
165
+ }
166
+ /**
167
+ * Returns `true` when `other` has the same algorithm and identical multihash
168
+ * bytes. The base is presentational and does not participate in equality, so
169
+ * the same digest encoded under different bases compares equal.
170
+ */
171
+ equals(other) {
172
+ return this.algorithm === other.algorithm && bytesEqual(this.multihash, other.multihash);
173
+ }
174
+ /**
175
+ * Re-hashes `data` with this digest's own algorithm and compares against the
176
+ * stored digest. Returns `false` only on a genuine digest mismatch; throws if
177
+ * `data` cannot be hashed (e.g. invalid input type). Callers must not wrap
178
+ * this in `.catch(() => false)`, which would mask real failures as mismatches.
179
+ */
180
+ async verify(data) {
181
+ const recomputed = await MultibaseDigest.fromData(data, {
182
+ algorithm: this.algorithm,
183
+ base: this.base,
184
+ });
185
+ return this.equals(recomputed);
186
+ }
187
+ }
188
+ //# sourceMappingURL=multibase-digest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multibase-digest.js","sourceRoot":"","sources":["../../src/multibase-digest/multibase-digest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,227 @@
1
+ import { base58btc } from 'multiformats/bases/base58';
2
+ import { MultibaseDigest } from './multibase-digest.js';
3
+ const encoder = new TextEncoder();
4
+ const helloBytes = encoder.encode('hello');
5
+ const worldBytes = encoder.encode('world');
6
+ const SHA256_HELLO_HEX = '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824';
7
+ const SHA256_EMPTY_HEX = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';
8
+ function toHex(bytes) {
9
+ return Array.from(bytes)
10
+ .map((b) => b.toString(16).padStart(2, '0'))
11
+ .join('');
12
+ }
13
+ describe('MultibaseDigest', () => {
14
+ describe('fromData', () => {
15
+ it('produces the expected SHA-256 digest of "hello"', async () => {
16
+ const digest = await MultibaseDigest.fromData(helloBytes, {
17
+ algorithm: 'sha2-256',
18
+ base: 'base58btc',
19
+ });
20
+ expect(digest.algorithm).toBe('sha2-256');
21
+ expect(digest.base).toBe('base58btc');
22
+ expect(digest.digest).toHaveLength(32);
23
+ expect(toHex(digest.digest)).toBe(SHA256_HELLO_HEX);
24
+ });
25
+ it('produces the expected SHA-256 digest of empty input', async () => {
26
+ const digest = await MultibaseDigest.fromData(new Uint8Array(0), {
27
+ algorithm: 'sha2-256',
28
+ base: 'base58btc',
29
+ });
30
+ expect(toHex(digest.digest)).toBe(SHA256_EMPTY_HEX);
31
+ });
32
+ it('encodes as base58btc with a leading "z"', async () => {
33
+ const digest = await MultibaseDigest.fromData(helloBytes, {
34
+ algorithm: 'sha2-256',
35
+ base: 'base58btc',
36
+ });
37
+ expect(digest.toString().startsWith('z')).toBe(true);
38
+ });
39
+ it('encodes as base64 with a leading "m"', async () => {
40
+ const digest = await MultibaseDigest.fromData(helloBytes, {
41
+ algorithm: 'sha2-256',
42
+ base: 'base64',
43
+ });
44
+ expect(digest.toString().startsWith('m')).toBe(true);
45
+ });
46
+ it('produces sha2-512 digests of length 64', async () => {
47
+ const digest = await MultibaseDigest.fromData(helloBytes, {
48
+ algorithm: 'sha2-512',
49
+ base: 'base58btc',
50
+ });
51
+ expect(digest.algorithm).toBe('sha2-512');
52
+ expect(digest.digest).toHaveLength(64);
53
+ });
54
+ it('rejects unsupported algorithms', async () => {
55
+ await expect(MultibaseDigest.fromData(helloBytes, {
56
+ algorithm: 'md5',
57
+ base: 'base58btc',
58
+ })).rejects.toThrow('Unsupported hash algorithm');
59
+ });
60
+ it('rejects unsupported bases', async () => {
61
+ await expect(MultibaseDigest.fromData(helloBytes, {
62
+ algorithm: 'sha2-256',
63
+ base: 'base16',
64
+ })).rejects.toThrow('Unsupported multibase encoding');
65
+ });
66
+ });
67
+ describe('fromDigest', () => {
68
+ it('wraps a precomputed digest without rehashing', async () => {
69
+ const hashed = await MultibaseDigest.fromData(helloBytes, {
70
+ algorithm: 'sha2-256',
71
+ base: 'base58btc',
72
+ });
73
+ const wrapped = MultibaseDigest.fromDigest(hashed.digest, {
74
+ algorithm: 'sha2-256',
75
+ base: 'base58btc',
76
+ });
77
+ expect(wrapped.toString()).toBe(hashed.toString());
78
+ expect(wrapped.equals(hashed)).toBe(true);
79
+ });
80
+ it('rejects unsupported algorithms', () => {
81
+ expect(() => MultibaseDigest.fromDigest(new Uint8Array(32), {
82
+ algorithm: 'md5',
83
+ base: 'base58btc',
84
+ })).toThrow('Unsupported hash algorithm');
85
+ });
86
+ it('rejects unsupported bases', () => {
87
+ expect(() => MultibaseDigest.fromDigest(new Uint8Array(32), {
88
+ algorithm: 'sha2-256',
89
+ base: 'base16',
90
+ })).toThrow('Unsupported multibase encoding');
91
+ });
92
+ it('rejects a digest whose length does not match the algorithm', () => {
93
+ // sha2-256 expects 32 bytes; a 16-byte digest is invalid.
94
+ expect(() => MultibaseDigest.fromDigest(new Uint8Array(16), {
95
+ algorithm: 'sha2-256',
96
+ base: 'base58btc',
97
+ })).toThrow('Digest length 16 does not match "sha2-256" (expected 32)');
98
+ // sha2-512 expects 64 bytes; a 32-byte digest is invalid.
99
+ expect(() => MultibaseDigest.fromDigest(new Uint8Array(32), {
100
+ algorithm: 'sha2-512',
101
+ base: 'base58btc',
102
+ })).toThrow('Digest length 32 does not match "sha2-512" (expected 64)');
103
+ });
104
+ });
105
+ describe('fromString', () => {
106
+ const supportedBases = ['base58btc', 'base64'];
107
+ const algorithms = ['sha2-256', 'sha2-512'];
108
+ it.each(supportedBases.flatMap((b) => algorithms.map((a) => [a, b])))('round-trips %s through %s', async (algorithm, base) => {
109
+ const original = await MultibaseDigest.fromData(helloBytes, { algorithm, base });
110
+ const encoded = original.toString();
111
+ const parsed = MultibaseDigest.fromString(encoded);
112
+ expect(parsed.algorithm).toBe(algorithm);
113
+ expect(parsed.base).toBe(base);
114
+ expect(parsed.equals(original)).toBe(true);
115
+ expect(parsed.toString()).toBe(encoded);
116
+ });
117
+ it('throws on an empty string', () => {
118
+ expect(() => MultibaseDigest.fromString('')).toThrow('non-empty');
119
+ });
120
+ it('throws on an unknown multibase prefix', () => {
121
+ // 'f' is the base16 prefix, which is not in our allow-list.
122
+ expect(() => MultibaseDigest.fromString('f1220')).toThrow('Unsupported multibase prefix');
123
+ });
124
+ it('throws with a decode error when the base58btc body contains non-alphabet characters', () => {
125
+ // 'z' selects base58btc; '0', 'O', 'I', 'l' are explicitly outside its alphabet.
126
+ expect(() => MultibaseDigest.fromString('z0OIl')).toThrow('Failed to decode multibase string');
127
+ });
128
+ it('throws on an unsupported multihash algorithm code', () => {
129
+ // sha1 = code 0x11, digest length 20. We don't support sha1.
130
+ const sha1Like = new Uint8Array(22);
131
+ sha1Like[0] = 0x11;
132
+ sha1Like[1] = 0x14;
133
+ const encoded = base58btc.encoder.encode(sha1Like);
134
+ expect(() => MultibaseDigest.fromString(encoded)).toThrow('Unsupported multihash algorithm code');
135
+ });
136
+ it('throws on malformed multihash bytes', () => {
137
+ // Claims sha2-256 (code 0x12) with 32-byte digest length (0x20) but has no data bytes.
138
+ const truncated = new Uint8Array([0x12, 0x20]);
139
+ const encoded = base58btc.encoder.encode(truncated);
140
+ expect(() => MultibaseDigest.fromString(encoded)).toThrow();
141
+ });
142
+ });
143
+ describe('toString', () => {
144
+ it('re-encodes in a different base without rehashing', async () => {
145
+ const digest = await MultibaseDigest.fromData(helloBytes, {
146
+ algorithm: 'sha2-256',
147
+ base: 'base64',
148
+ });
149
+ const b58 = digest.toString('base58btc');
150
+ expect(b58.startsWith('z')).toBe(true);
151
+ const reparsed = MultibaseDigest.fromString(b58);
152
+ expect(reparsed.equals(digest)).toBe(true);
153
+ });
154
+ it('rejects unsupported base requests', async () => {
155
+ const digest = await MultibaseDigest.fromData(helloBytes, {
156
+ algorithm: 'sha2-256',
157
+ base: 'base58btc',
158
+ });
159
+ expect(() => digest.toString('base16')).toThrow('Unsupported multibase encoding');
160
+ });
161
+ });
162
+ describe('equals', () => {
163
+ it('treats the same digest encoded in different bases as equal', async () => {
164
+ const a = await MultibaseDigest.fromData(helloBytes, {
165
+ algorithm: 'sha2-256',
166
+ base: 'base64',
167
+ });
168
+ const b = MultibaseDigest.fromString(a.toString('base58btc'));
169
+ expect(a.equals(b)).toBe(true);
170
+ });
171
+ it('returns false for different data', async () => {
172
+ const a = await MultibaseDigest.fromData(helloBytes, {
173
+ algorithm: 'sha2-256',
174
+ base: 'base58btc',
175
+ });
176
+ const b = await MultibaseDigest.fromData(worldBytes, {
177
+ algorithm: 'sha2-256',
178
+ base: 'base58btc',
179
+ });
180
+ expect(a.equals(b)).toBe(false);
181
+ });
182
+ it('returns false for a single-byte difference at the same length', () => {
183
+ const base = new Uint8Array(32);
184
+ const variant = new Uint8Array(32);
185
+ variant[7] = 0x01;
186
+ const a = MultibaseDigest.fromDigest(base, { algorithm: 'sha2-256', base: 'base58btc' });
187
+ const b = MultibaseDigest.fromDigest(variant, { algorithm: 'sha2-256', base: 'base58btc' });
188
+ expect(a.equals(b)).toBe(false);
189
+ });
190
+ it('returns false for different algorithms over the same data', async () => {
191
+ const a = await MultibaseDigest.fromData(helloBytes, {
192
+ algorithm: 'sha2-256',
193
+ base: 'base58btc',
194
+ });
195
+ const b = await MultibaseDigest.fromData(helloBytes, {
196
+ algorithm: 'sha2-512',
197
+ base: 'base58btc',
198
+ });
199
+ expect(a.equals(b)).toBe(false);
200
+ });
201
+ });
202
+ describe('verify', () => {
203
+ it('returns true for matching data', async () => {
204
+ const digest = await MultibaseDigest.fromData(helloBytes, {
205
+ algorithm: 'sha2-256',
206
+ base: 'base58btc',
207
+ });
208
+ expect(await digest.verify(helloBytes)).toBe(true);
209
+ });
210
+ it('returns false for non-matching data', async () => {
211
+ const digest = await MultibaseDigest.fromData(helloBytes, {
212
+ algorithm: 'sha2-256',
213
+ base: 'base58btc',
214
+ });
215
+ expect(await digest.verify(worldBytes)).toBe(false);
216
+ });
217
+ it("uses the digest's own algorithm, not the caller's", async () => {
218
+ const digest512 = await MultibaseDigest.fromData(helloBytes, {
219
+ algorithm: 'sha2-512',
220
+ base: 'base58btc',
221
+ });
222
+ // verify() must re-hash with sha2-512, not assume sha2-256.
223
+ expect(await digest512.verify(helloBytes)).toBe(true);
224
+ });
225
+ });
226
+ });
227
+ //# sourceMappingURL=multibase-digest.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multibase-digest.test.js","sourceRoot":"","sources":["../../src/multibase-digest/multibase-digest.test.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@uncefact/untp-utils",
3
+ "version": "0.0.1",
4
+ "description": "Shared utility primitives for UNTP packages and consumers.",
5
+ "main": "./build/index.js",
6
+ "types": "./build/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./build/index.d.ts",
10
+ "default": "./build/index.js"
11
+ },
12
+ "./multibase-digest": {
13
+ "types": "./build/multibase-digest/index.d.ts",
14
+ "default": "./build/multibase-digest/index.js"
15
+ }
16
+ },
17
+ "typesVersions": {
18
+ "*": {
19
+ "multibase-digest": [
20
+ "./build/multibase-digest/index.d.ts"
21
+ ]
22
+ }
23
+ },
24
+ "files": [
25
+ "build"
26
+ ],
27
+ "type": "module",
28
+ "keywords": [
29
+ "untp",
30
+ "multibase",
31
+ "multihash",
32
+ "digest"
33
+ ],
34
+ "author": "",
35
+ "license": "ISC",
36
+ "dependencies": {
37
+ "multiformats": "^13.3.1"
38
+ },
39
+ "devDependencies": {
40
+ "@types/jest": "29.5.11",
41
+ "cross-env": "^7.0.3",
42
+ "jest": "29.7.0",
43
+ "ts-jest": "29.1.1",
44
+ "typescript": "^5.3.3"
45
+ },
46
+ "scripts": {
47
+ "build": "tsc --build --clean && tsc",
48
+ "watch": "tsc -b --watch",
49
+ "test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest",
50
+ "test:coverage": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --coverage"
51
+ }
52
+ }