@midnight-ntwrk/credential-compact 0.1.0-rc3 → 0.2.0-rc1
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/CHANGELOG.md +43 -1
- package/README.md +47 -27
- package/dist/compact-build.json +6 -13
- package/dist/compact-value-codec.d.ts +14 -0
- package/dist/compact-value-codec.d.ts.map +1 -0
- package/dist/compact-value-codec.js +135 -0
- package/dist/compact-value-codec.js.map +1 -0
- package/dist/credentials/composable.compact +1 -3
- package/dist/credentials/holder-bindings.compact +11 -289
- package/dist/credentials/proofs.compact +85 -0
- package/dist/credentials/relations.compact +3 -2
- package/dist/credentials/signer-authorization.compact +246 -0
- package/dist/credentials/status-bindings.compact +0 -19
- package/dist/credentials/types.compact +23 -93
- package/dist/credentials/vc.compact +24 -3
- package/dist/credentials.compact +0 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/managed/credentials/contract/index.d.ts +102 -196
- package/dist/managed/credentials/contract/index.js +746 -1342
- package/dist/managed/credentials/contract/index.js.map +2 -2
- package/package.json +12 -53
- package/dist/contract.d.ts +0 -2
- package/dist/contract.d.ts.map +0 -1
- package/dist/contract.js +0 -2
- package/dist/contract.js.map +0 -1
- package/dist/credentials/bindings.compact +0 -5
- package/dist/credentials/issue.compact +0 -91
- package/dist/credentials/present.compact +0 -84
- package/dist/credentials/protocol-support.compact +0 -7
- package/dist/credentials/protocols.compact +0 -125
- package/dist/credentials/vc-support.compact +0 -8
- package/dist/holder-binding/same-holder/composable.compact +0 -179
- package/dist/holder-binding/same-holder.compact +0 -180
- package/dist/holder-binding/same-holder.d.ts +0 -2
- package/dist/holder-binding/same-holder.d.ts.map +0 -1
- package/dist/holder-binding/same-holder.js +0 -2
- package/dist/holder-binding/same-holder.js.map +0 -1
- package/dist/jubjub.d.ts +0 -3
- package/dist/jubjub.d.ts.map +0 -1
- package/dist/jubjub.js +0 -6
- package/dist/jubjub.js.map +0 -1
- package/dist/managed/same-holder/contract/index.d.ts +0 -400
- package/dist/managed/same-holder/contract/index.js +0 -2688
- package/dist/managed/same-holder/contract/index.js.map +0 -8
- package/src/credentials/bindings.compact +0 -5
- package/src/credentials/composable.compact +0 -14
- package/src/credentials/holder-bindings.compact +0 -320
- package/src/credentials/issue.compact +0 -91
- package/src/credentials/present.compact +0 -84
- package/src/credentials/proofs.compact +0 -122
- package/src/credentials/protocol-support.compact +0 -7
- package/src/credentials/protocols.compact +0 -125
- package/src/credentials/relations.compact +0 -36
- package/src/credentials/status-bindings.compact +0 -60
- package/src/credentials/types.compact +0 -141
- package/src/credentials/vc-support.compact +0 -8
- package/src/credentials/vc.compact +0 -59
- package/src/credentials/vp.compact +0 -25
- package/src/credentials.compact +0 -20
- package/src/holder-binding/same-holder/composable.compact +0 -179
- package/src/holder-binding/same-holder.compact +0 -180
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,52 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.0 - 2026-09-18
|
|
4
|
+
|
|
5
|
+
- Classified every exported Compact circuit and added fail-closed coverage for
|
|
6
|
+
envelope invariants, verification-method references, proof contexts, and
|
|
7
|
+
credential and presentation body substitution.
|
|
8
|
+
- Reject caller-supplied credential body roots that do not equal the canonical
|
|
9
|
+
root recomputed from the complete credential before issuer-proof validation.
|
|
10
|
+
- Bind credential presentations to the exact credential schema and add
|
|
11
|
+
positive and substitution-negative conformance for VC/VP relations, explicit
|
|
12
|
+
holder-proof references, and structural status bindings.
|
|
13
|
+
- Added source-neutral issuer/verifier authorization descriptors, signature and
|
|
14
|
+
exact method/key/scope binding circuits, monotonic lifecycle validation, and
|
|
15
|
+
domain-separated Jubjub authority and verifier-request proof contexts without
|
|
16
|
+
introducing Trust Registry or datetime dependencies.
|
|
17
|
+
- Documented `midnight-did` `0.6.0` as the current downstream adapter
|
|
18
|
+
compatibility baseline while keeping the Compact package DID-independent.
|
|
19
|
+
- Bound authority decisions to an explicit consumer/network domain, made
|
|
20
|
+
revocation terminal per authorization ID, validated Jubjub subgroup
|
|
21
|
+
membership, and added a credential-derived issuer authorization helper.
|
|
22
|
+
- Hardened all context-specific proofs against invalid verification-method
|
|
23
|
+
references and identity, off-curve, or torsion public-key and nonce points.
|
|
24
|
+
- BREAKING: renamed `VerificationMethodRef.didContractAddress` to
|
|
25
|
+
`controllerAddress` so the core can reference DID, registry, or other
|
|
26
|
+
verification-method controllers without choosing a DID method.
|
|
27
|
+
- Verification-method validation now rejects zero controller addresses across
|
|
28
|
+
holder and status bindings, and holder equality checks reject invalid refs.
|
|
29
|
+
- BREAKING: removed the single-value status enum and no-op no-status validator.
|
|
30
|
+
The smaller `RegistryBoundStatusBinding` layout changes its persistent hash
|
|
31
|
+
from the `0.1.x` package surface.
|
|
32
|
+
- Removed the unrelated TypeScript Jubjub scalar helper from the VC package
|
|
33
|
+
surface.
|
|
34
|
+
- Removed experimental secret-holder, blinded-holder, pseudonym, and
|
|
35
|
+
same-holder circuits. The package now supports explicit holder binding only.
|
|
36
|
+
- Removed unused issuance and presentation protocol choreography from the
|
|
37
|
+
family-neutral Compact source surface.
|
|
38
|
+
- Reduced the package to one standalone Compact root and one composition-safe
|
|
39
|
+
Compact root.
|
|
40
|
+
- Removed unused schema-discovery descriptors, method-specific legacy holder
|
|
41
|
+
bindings, and three-credential business helpers.
|
|
42
|
+
- Removed duplicate `src` copies and redundant TypeScript subpath exports from
|
|
43
|
+
the package tarball; Compact sources remain available through `dist` exports.
|
|
44
|
+
|
|
3
45
|
## 0.1.0 - RC2 supported prerelease
|
|
4
46
|
|
|
5
47
|
- Extracted curated family-neutral Compact VC/VP semantics from the internal
|
|
6
48
|
credentials package.
|
|
7
49
|
- Excluded verification-v1, authority contracts, family code, and private
|
|
8
50
|
proving/deployment material.
|
|
9
|
-
- Added audited same-holder
|
|
51
|
+
- Added audited same-holder circuits and semantic vectors.
|
|
10
52
|
- Promoted the package into the supported RC2 development surface.
|
package/README.md
CHANGED
|
@@ -11,46 +11,66 @@ credential family, proof artifact, or registry authority.
|
|
|
11
11
|
## Scope
|
|
12
12
|
|
|
13
13
|
The package contains generic VC/VP envelopes, schema references, issuer and
|
|
14
|
-
holder-binding shapes, proof/challenge primitives,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
holder-binding shapes, proof/challenge primitives, VC-side status-binding
|
|
15
|
+
shapes, source-neutral signer-authorization descriptors and binding helpers,
|
|
16
|
+
VC/VP linkage helpers, and
|
|
17
|
+
protocol-neutral `compact-value-v1.base64url` TypeScript framing for canonical
|
|
18
|
+
Compact runtime values. `StatusRegistryRef` is vocabulary only: this package
|
|
19
|
+
does not authenticate registry mutation, roots, time, witnesses, or final
|
|
20
|
+
non-membership.
|
|
18
21
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
Context-specific proof helpers validate signer references, reject identity,
|
|
23
|
+
off-curve, and non-prime-subgroup Jubjub public keys and nonce points, derive
|
|
24
|
+
domain-separated challenges, and verify Schnorr signatures. Signed timestamps
|
|
25
|
+
and challenge hashes still require application-defined time, freshness,
|
|
26
|
+
audience, and replay policy.
|
|
27
|
+
|
|
28
|
+
Signer authorization supports two composition modes. Applications may install
|
|
29
|
+
an accepted descriptor through local governance, or verify a domain-separated
|
|
30
|
+
authority proof before materializing the same descriptor. The authorization
|
|
31
|
+
proof is bound to a caller-configured network/consumer domain. The composed
|
|
32
|
+
`VC<>::assertAuthorizedIssuerProof` and verifier-request helper verify the
|
|
33
|
+
signature as well as the exact role, method, key, and scope binding. This
|
|
34
|
+
package does not resolve
|
|
35
|
+
`midnight-did`, evaluate Trust Registry policy, synchronize registry state, or
|
|
36
|
+
provide trusted wall-clock time.
|
|
37
|
+
|
|
38
|
+
`verification-v1`, issuance/presentation protocol choreography, family claims
|
|
39
|
+
and predicates, status-registry authority, proving/deployment artifacts,
|
|
40
|
+
wallets, signing keys, witnesses, secrets, and use-case code are deliberately
|
|
41
|
+
excluded.
|
|
22
42
|
|
|
23
43
|
## Toolchain and generated output
|
|
24
44
|
|
|
25
|
-
The
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
`dist` are generated during build and are not hand-edited.
|
|
45
|
+
The package is compiled with the pinned Compact `0.31.1` compiler and exactly
|
|
46
|
+
`@midnight-ntwrk/compact-runtime` `0.16.0`. Builds verify both versions, then
|
|
47
|
+
regenerate `src/managed` and `dist`; neither directory is hand-edited.
|
|
29
48
|
`dist/compact-build.json` records the exact compiler/runtime tuple, source digest,
|
|
30
49
|
and generated-artifact digest.
|
|
31
50
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
`credentials` root) first, then include the fragment exactly once. The other
|
|
51
|
+
`./credentials.compact` is the only standalone root.
|
|
52
|
+
`./credentials/composable.compact` is the only composition-safe root: include it
|
|
53
|
+
exactly once before dependency-free family composition entrypoints. The other
|
|
36
54
|
credential leaf modules remain packaged for internal composition but are not
|
|
37
55
|
advertised as standalone exports because they rely on declarations supplied by
|
|
38
56
|
the shared root.
|
|
39
57
|
|
|
40
|
-
The external consumer gate compiles both
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
58
|
+
The external consumer gate compiles both canonical roots from the packed
|
|
59
|
+
tarball. Hidden-holder, pseudonym, and same-holder semantics require a dedicated
|
|
60
|
+
threat model and belong in independently versioned credential-family packages.
|
|
61
|
+
The repository's
|
|
62
|
+
[`compact-circuits.json`](../../../conformance/compact-circuits.json) inventory
|
|
63
|
+
classifies the complete exported circuit surface and distinguishes supported
|
|
64
|
+
semantic operations from low-level composition primitives.
|
|
44
65
|
|
|
45
|
-
##
|
|
66
|
+
## Ownership
|
|
46
67
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
not normative ADR acceptance.
|
|
68
|
+
This package is the single canonical owner of reusable Compact VC/VP semantics.
|
|
69
|
+
The retired compatibility packages are not part of the workspace or release
|
|
70
|
+
surface. Their `verification-v1`, status-attestation, and hidden-holder
|
|
71
|
+
entrypoints are not supported by this package. Technical ownership is the VC
|
|
72
|
+
package maintainers; release operation and incident ownership are defined by
|
|
73
|
+
the repository's npm publication runbook.
|
|
54
74
|
|
|
55
75
|
## Usage boundary
|
|
56
76
|
|
package/dist/compact-build.json
CHANGED
|
@@ -1,29 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": 1,
|
|
3
|
-
"compiler": "0.
|
|
3
|
+
"compiler": "0.31.1",
|
|
4
4
|
"runtime": {
|
|
5
5
|
"name": "@midnight-ntwrk/compact-runtime",
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.16.0"
|
|
7
7
|
},
|
|
8
|
-
"sourceDigest": "
|
|
9
|
-
"artifactDigest": "
|
|
8
|
+
"sourceDigest": "6058807adf9e4ee137d69deb9ca236bb9d0c31cd5bb6794a7130ec79164621b9",
|
|
9
|
+
"artifactDigest": "9506e06d6dd6d010bdad1f9ffbbf3eed9b508fcfd5589af024da47595f5c74c5",
|
|
10
10
|
"sourceFiles": [
|
|
11
|
-
"src/credentials/bindings.compact",
|
|
12
11
|
"src/credentials/composable.compact",
|
|
13
12
|
"src/credentials/holder-bindings.compact",
|
|
14
|
-
"src/credentials/issue.compact",
|
|
15
|
-
"src/credentials/present.compact",
|
|
16
13
|
"src/credentials/proofs.compact",
|
|
17
|
-
"src/credentials/protocol-support.compact",
|
|
18
|
-
"src/credentials/protocols.compact",
|
|
19
14
|
"src/credentials/relations.compact",
|
|
15
|
+
"src/credentials/signer-authorization.compact",
|
|
20
16
|
"src/credentials/status-bindings.compact",
|
|
21
17
|
"src/credentials/types.compact",
|
|
22
|
-
"src/credentials/vc-support.compact",
|
|
23
18
|
"src/credentials/vc.compact",
|
|
24
19
|
"src/credentials/vp.compact",
|
|
25
|
-
"src/credentials.compact"
|
|
26
|
-
"src/holder-binding/same-holder/composable.compact",
|
|
27
|
-
"src/holder-binding/same-holder.compact"
|
|
20
|
+
"src/credentials.compact"
|
|
28
21
|
]
|
|
29
22
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CompactType, Value } from "@midnight-ntwrk/compact-runtime";
|
|
2
|
+
export declare const COMPACT_VALUE_ENCODING: "compact-value-v1.base64url";
|
|
3
|
+
export type CompactValueEncoding = typeof COMPACT_VALUE_ENCODING;
|
|
4
|
+
export type EncodedCompactValue = {
|
|
5
|
+
readonly encoding: CompactValueEncoding;
|
|
6
|
+
readonly payload: string;
|
|
7
|
+
};
|
|
8
|
+
export declare const compactValueToBytes: (value: readonly Uint8Array[]) => Uint8Array;
|
|
9
|
+
export declare const compactValueFromBytes: (bytes: Uint8Array) => Value;
|
|
10
|
+
export declare const encodeCompactValue: (value: readonly Uint8Array[]) => EncodedCompactValue;
|
|
11
|
+
export declare const decodeCompactValue: (encoded: EncodedCompactValue) => Value;
|
|
12
|
+
export declare const encodeCompactPayload: <T>(descriptor: CompactType<T>, value: T) => EncodedCompactValue;
|
|
13
|
+
export declare const decodeCompactPayload: <T>(descriptor: CompactType<T>, encoded: EncodedCompactValue) => T;
|
|
14
|
+
//# sourceMappingURL=compact-value-codec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compact-value-codec.d.ts","sourceRoot":"","sources":["../src/compact-value-codec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,iCAAiC,CAAC;AAE1E,eAAO,MAAM,sBAAsB,EAAG,4BAAqC,CAAC;AAS5E,MAAM,MAAM,oBAAoB,GAAG,OAAO,sBAAsB,CAAC;AAEjE,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;AAgFF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,SAAS,UAAU,EAAE,KAC3B,UAiBF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,OAAO,UAAU,KAAG,KAyBzD,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,OAAO,SAAS,UAAU,EAAE,KAC3B,mBAGD,CAAC;AAEH,eAAO,MAAM,kBAAkB,GAAI,SAAS,mBAAmB,KAAG,KAKjE,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,CAAC,EACpC,YAAY,WAAW,CAAC,CAAC,CAAC,EAC1B,OAAO,CAAC,KACP,mBAAoE,CAAC;AAExE,eAAO,MAAM,oBAAoB,GAAI,CAAC,EACpC,YAAY,WAAW,CAAC,CAAC,CAAC,EAC1B,SAAS,mBAAmB,KAC3B,CASF,CAAC"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
export const COMPACT_VALUE_ENCODING = "compact-value-v1.base64url";
|
|
2
|
+
const MAGIC = new Uint8Array([0x4d, 0x43, 0x56, 0x31]); // MCV1
|
|
3
|
+
const HEADER_LENGTH = MAGIC.length + 4;
|
|
4
|
+
const CHUNK_LENGTH_BYTES = 4;
|
|
5
|
+
const BASE64URL_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
6
|
+
const BASE64URL_TEXT = /^[A-Za-z0-9_-]+$/u;
|
|
7
|
+
const assertUint32 = (value, label) => {
|
|
8
|
+
if (!Number.isInteger(value) || value < 0 || value > 0xffffffff) {
|
|
9
|
+
throw new Error(`${label} must fit into uint32`);
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
const writeUint32 = (target, offset, value) => {
|
|
13
|
+
assertUint32(value, "uint32 value");
|
|
14
|
+
target[offset] = (value >>> 24) & 0xff;
|
|
15
|
+
target[offset + 1] = (value >>> 16) & 0xff;
|
|
16
|
+
target[offset + 2] = (value >>> 8) & 0xff;
|
|
17
|
+
target[offset + 3] = value & 0xff;
|
|
18
|
+
};
|
|
19
|
+
const readUint32 = (source, offset) => {
|
|
20
|
+
if (offset + CHUNK_LENGTH_BYTES > source.length) {
|
|
21
|
+
throw new Error("Compact value payload ended before uint32 field");
|
|
22
|
+
}
|
|
23
|
+
return (source[offset] * 0x1000000 +
|
|
24
|
+
((source[offset + 1] ?? 0) << 16) +
|
|
25
|
+
((source[offset + 2] ?? 0) << 8) +
|
|
26
|
+
(source[offset + 3] ?? 0));
|
|
27
|
+
};
|
|
28
|
+
const toBase64Url = (bytes) => {
|
|
29
|
+
let encoded = "";
|
|
30
|
+
for (let offset = 0; offset < bytes.length; offset += 3) {
|
|
31
|
+
const first = bytes[offset] ?? 0;
|
|
32
|
+
const second = bytes[offset + 1] ?? 0;
|
|
33
|
+
const third = bytes[offset + 2] ?? 0;
|
|
34
|
+
const packed = (first << 16) | (second << 8) | third;
|
|
35
|
+
encoded += BASE64URL_ALPHABET[(packed >>> 18) & 0x3f];
|
|
36
|
+
encoded += BASE64URL_ALPHABET[(packed >>> 12) & 0x3f];
|
|
37
|
+
if (offset + 1 < bytes.length) {
|
|
38
|
+
encoded += BASE64URL_ALPHABET[(packed >>> 6) & 0x3f];
|
|
39
|
+
}
|
|
40
|
+
if (offset + 2 < bytes.length) {
|
|
41
|
+
encoded += BASE64URL_ALPHABET[packed & 0x3f];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return encoded;
|
|
45
|
+
};
|
|
46
|
+
const fromBase64Url = (value) => {
|
|
47
|
+
if (value.length === 0) {
|
|
48
|
+
throw new Error("Compact value payload must not be empty");
|
|
49
|
+
}
|
|
50
|
+
if (!BASE64URL_TEXT.test(value) || value.length % 4 === 1) {
|
|
51
|
+
throw new Error("Compact value payload is not valid unpadded base64url");
|
|
52
|
+
}
|
|
53
|
+
const decoded = new Uint8Array(Math.floor((value.length * 6) / 8));
|
|
54
|
+
let accumulator = 0;
|
|
55
|
+
let bitCount = 0;
|
|
56
|
+
let outputOffset = 0;
|
|
57
|
+
for (const character of value) {
|
|
58
|
+
const index = BASE64URL_ALPHABET.indexOf(character);
|
|
59
|
+
accumulator = (accumulator << 6) | index;
|
|
60
|
+
bitCount += 6;
|
|
61
|
+
if (bitCount >= 8) {
|
|
62
|
+
bitCount -= 8;
|
|
63
|
+
decoded[outputOffset] = (accumulator >>> bitCount) & 0xff;
|
|
64
|
+
outputOffset += 1;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (toBase64Url(decoded) !== value) {
|
|
68
|
+
throw new Error("Compact value payload is not canonical unpadded base64url");
|
|
69
|
+
}
|
|
70
|
+
return decoded;
|
|
71
|
+
};
|
|
72
|
+
export const compactValueToBytes = (value) => {
|
|
73
|
+
assertUint32(value.length, "Compact value chunk count");
|
|
74
|
+
const bodyLength = value.reduce((total, chunk) => {
|
|
75
|
+
assertUint32(chunk.length, "Compact value chunk length");
|
|
76
|
+
return total + CHUNK_LENGTH_BYTES + chunk.length;
|
|
77
|
+
}, 0);
|
|
78
|
+
const result = new Uint8Array(HEADER_LENGTH + bodyLength);
|
|
79
|
+
result.set(MAGIC, 0);
|
|
80
|
+
writeUint32(result, MAGIC.length, value.length);
|
|
81
|
+
let offset = HEADER_LENGTH;
|
|
82
|
+
for (const chunk of value) {
|
|
83
|
+
writeUint32(result, offset, chunk.length);
|
|
84
|
+
offset += CHUNK_LENGTH_BYTES;
|
|
85
|
+
result.set(chunk, offset);
|
|
86
|
+
offset += chunk.length;
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
89
|
+
};
|
|
90
|
+
export const compactValueFromBytes = (bytes) => {
|
|
91
|
+
if (bytes.length < HEADER_LENGTH) {
|
|
92
|
+
throw new Error("Compact value payload is shorter than the header");
|
|
93
|
+
}
|
|
94
|
+
for (let i = 0; i < MAGIC.length; i += 1) {
|
|
95
|
+
if (bytes[i] !== MAGIC[i]) {
|
|
96
|
+
throw new Error("Compact value payload has an unexpected magic header");
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const chunkCount = readUint32(bytes, MAGIC.length);
|
|
100
|
+
const chunks = [];
|
|
101
|
+
let offset = HEADER_LENGTH;
|
|
102
|
+
for (let i = 0; i < chunkCount; i += 1) {
|
|
103
|
+
const length = readUint32(bytes, offset);
|
|
104
|
+
offset += CHUNK_LENGTH_BYTES;
|
|
105
|
+
if (offset + length > bytes.length) {
|
|
106
|
+
throw new Error("Compact value chunk exceeds payload length");
|
|
107
|
+
}
|
|
108
|
+
chunks.push(bytes.slice(offset, offset + length));
|
|
109
|
+
offset += length;
|
|
110
|
+
}
|
|
111
|
+
if (offset !== bytes.length) {
|
|
112
|
+
throw new Error("Compact value payload contains trailing bytes");
|
|
113
|
+
}
|
|
114
|
+
return chunks;
|
|
115
|
+
};
|
|
116
|
+
export const encodeCompactValue = (value) => ({
|
|
117
|
+
encoding: COMPACT_VALUE_ENCODING,
|
|
118
|
+
payload: toBase64Url(compactValueToBytes(value)),
|
|
119
|
+
});
|
|
120
|
+
export const decodeCompactValue = (encoded) => {
|
|
121
|
+
if (encoded.encoding !== COMPACT_VALUE_ENCODING) {
|
|
122
|
+
throw new Error(`Unsupported Compact value encoding "${encoded.encoding}"`);
|
|
123
|
+
}
|
|
124
|
+
return compactValueFromBytes(fromBase64Url(encoded.payload));
|
|
125
|
+
};
|
|
126
|
+
export const encodeCompactPayload = (descriptor, value) => encodeCompactValue(descriptor.toValue(value));
|
|
127
|
+
export const decodeCompactPayload = (descriptor, encoded) => {
|
|
128
|
+
const runtimeValue = decodeCompactValue(encoded);
|
|
129
|
+
const decoded = descriptor.fromValue(runtimeValue);
|
|
130
|
+
if (runtimeValue.length !== 0) {
|
|
131
|
+
throw new Error("Compact value payload contains trailing chunks for descriptor");
|
|
132
|
+
}
|
|
133
|
+
return decoded;
|
|
134
|
+
};
|
|
135
|
+
//# sourceMappingURL=compact-value-codec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compact-value-codec.js","sourceRoot":"","sources":["../src/compact-value-codec.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CompactType, Value } from \"@midnight-ntwrk/compact-runtime\";\n\nexport const COMPACT_VALUE_ENCODING = \"compact-value-v1.base64url\" as const;\n\nconst MAGIC = new Uint8Array([0x4d, 0x43, 0x56, 0x31]); // MCV1\nconst HEADER_LENGTH = MAGIC.length + 4;\nconst CHUNK_LENGTH_BYTES = 4;\nconst BASE64URL_ALPHABET =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\nconst BASE64URL_TEXT = /^[A-Za-z0-9_-]+$/u;\n\nexport type CompactValueEncoding = typeof COMPACT_VALUE_ENCODING;\n\nexport type EncodedCompactValue = {\n readonly encoding: CompactValueEncoding;\n readonly payload: string;\n};\n\nconst assertUint32 = (value: number, label: string): void => {\n if (!Number.isInteger(value) || value < 0 || value > 0xffffffff) {\n throw new Error(`${label} must fit into uint32`);\n }\n};\n\nconst writeUint32 = (\n target: Uint8Array,\n offset: number,\n value: number,\n): void => {\n assertUint32(value, \"uint32 value\");\n target[offset] = (value >>> 24) & 0xff;\n target[offset + 1] = (value >>> 16) & 0xff;\n target[offset + 2] = (value >>> 8) & 0xff;\n target[offset + 3] = value & 0xff;\n};\n\nconst readUint32 = (source: Uint8Array, offset: number): number => {\n if (offset + CHUNK_LENGTH_BYTES > source.length) {\n throw new Error(\"Compact value payload ended before uint32 field\");\n }\n return (\n source[offset] * 0x1000000 +\n ((source[offset + 1] ?? 0) << 16) +\n ((source[offset + 2] ?? 0) << 8) +\n (source[offset + 3] ?? 0)\n );\n};\n\nconst toBase64Url = (bytes: Uint8Array): string => {\n let encoded = \"\";\n for (let offset = 0; offset < bytes.length; offset += 3) {\n const first = bytes[offset] ?? 0;\n const second = bytes[offset + 1] ?? 0;\n const third = bytes[offset + 2] ?? 0;\n const packed = (first << 16) | (second << 8) | third;\n encoded += BASE64URL_ALPHABET[(packed >>> 18) & 0x3f];\n encoded += BASE64URL_ALPHABET[(packed >>> 12) & 0x3f];\n if (offset + 1 < bytes.length) {\n encoded += BASE64URL_ALPHABET[(packed >>> 6) & 0x3f];\n }\n if (offset + 2 < bytes.length) {\n encoded += BASE64URL_ALPHABET[packed & 0x3f];\n }\n }\n return encoded;\n};\n\nconst fromBase64Url = (value: string): Uint8Array => {\n if (value.length === 0) {\n throw new Error(\"Compact value payload must not be empty\");\n }\n if (!BASE64URL_TEXT.test(value) || value.length % 4 === 1) {\n throw new Error(\"Compact value payload is not valid unpadded base64url\");\n }\n const decoded = new Uint8Array(Math.floor((value.length * 6) / 8));\n let accumulator = 0;\n let bitCount = 0;\n let outputOffset = 0;\n for (const character of value) {\n const index = BASE64URL_ALPHABET.indexOf(character);\n accumulator = (accumulator << 6) | index;\n bitCount += 6;\n if (bitCount >= 8) {\n bitCount -= 8;\n decoded[outputOffset] = (accumulator >>> bitCount) & 0xff;\n outputOffset += 1;\n }\n }\n if (toBase64Url(decoded) !== value) {\n throw new Error(\n \"Compact value payload is not canonical unpadded base64url\",\n );\n }\n return decoded;\n};\n\nexport const compactValueToBytes = (\n value: readonly Uint8Array[],\n): Uint8Array => {\n assertUint32(value.length, \"Compact value chunk count\");\n const bodyLength = value.reduce((total, chunk) => {\n assertUint32(chunk.length, \"Compact value chunk length\");\n return total + CHUNK_LENGTH_BYTES + chunk.length;\n }, 0);\n const result = new Uint8Array(HEADER_LENGTH + bodyLength);\n result.set(MAGIC, 0);\n writeUint32(result, MAGIC.length, value.length);\n let offset = HEADER_LENGTH;\n for (const chunk of value) {\n writeUint32(result, offset, chunk.length);\n offset += CHUNK_LENGTH_BYTES;\n result.set(chunk, offset);\n offset += chunk.length;\n }\n return result;\n};\n\nexport const compactValueFromBytes = (bytes: Uint8Array): Value => {\n if (bytes.length < HEADER_LENGTH) {\n throw new Error(\"Compact value payload is shorter than the header\");\n }\n for (let i = 0; i < MAGIC.length; i += 1) {\n if (bytes[i] !== MAGIC[i]) {\n throw new Error(\"Compact value payload has an unexpected magic header\");\n }\n }\n const chunkCount = readUint32(bytes, MAGIC.length);\n const chunks: Uint8Array[] = [];\n let offset = HEADER_LENGTH;\n for (let i = 0; i < chunkCount; i += 1) {\n const length = readUint32(bytes, offset);\n offset += CHUNK_LENGTH_BYTES;\n if (offset + length > bytes.length) {\n throw new Error(\"Compact value chunk exceeds payload length\");\n }\n chunks.push(bytes.slice(offset, offset + length));\n offset += length;\n }\n if (offset !== bytes.length) {\n throw new Error(\"Compact value payload contains trailing bytes\");\n }\n return chunks;\n};\n\nexport const encodeCompactValue = (\n value: readonly Uint8Array[],\n): EncodedCompactValue => ({\n encoding: COMPACT_VALUE_ENCODING,\n payload: toBase64Url(compactValueToBytes(value)),\n});\n\nexport const decodeCompactValue = (encoded: EncodedCompactValue): Value => {\n if (encoded.encoding !== COMPACT_VALUE_ENCODING) {\n throw new Error(`Unsupported Compact value encoding \"${encoded.encoding}\"`);\n }\n return compactValueFromBytes(fromBase64Url(encoded.payload));\n};\n\nexport const encodeCompactPayload = <T>(\n descriptor: CompactType<T>,\n value: T,\n): EncodedCompactValue => encodeCompactValue(descriptor.toValue(value));\n\nexport const decodeCompactPayload = <T>(\n descriptor: CompactType<T>,\n encoded: EncodedCompactValue,\n): T => {\n const runtimeValue = decodeCompactValue(encoded);\n const decoded = descriptor.fromValue(runtimeValue);\n if (runtimeValue.length !== 0) {\n throw new Error(\n \"Compact value payload contains trailing chunks for descriptor\",\n );\n }\n return decoded;\n};\n"]}
|
|
@@ -4,11 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
include "./types";
|
|
6
6
|
include "./proofs";
|
|
7
|
+
include "./signer-authorization";
|
|
7
8
|
include "./vc";
|
|
8
9
|
include "./vp";
|
|
9
10
|
include "./relations";
|
|
10
11
|
include "./holder-bindings";
|
|
11
|
-
include "./protocols";
|
|
12
|
-
include "./issue";
|
|
13
|
-
include "./present";
|
|
14
12
|
include "./status-bindings";
|