@bitspark/archon-sdk 0.14.0 → 0.15.0
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/dist/src/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export * from "./envelope.js";
|
|
|
4
4
|
export * from "./login.js";
|
|
5
5
|
export * from "./login-audience.js";
|
|
6
6
|
export * from "./login-display.js";
|
|
7
|
+
export * from "./login-fingerprint.js";
|
|
7
8
|
export * from "./enroll.js";
|
|
8
9
|
export * from "./enroll-token.js";
|
|
9
10
|
export * from "./request.js";
|
package/dist/src/index.js
CHANGED
|
@@ -22,6 +22,7 @@ export * from "./envelope.js";
|
|
|
22
22
|
export * from "./login.js";
|
|
23
23
|
export * from "./login-audience.js";
|
|
24
24
|
export * from "./login-display.js";
|
|
25
|
+
export * from "./login-fingerprint.js";
|
|
25
26
|
export * from "./enroll.js";
|
|
26
27
|
export * from "./enroll-token.js";
|
|
27
28
|
export * from "./request.js";
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,EAAE;AACF,uFAAuF;AACvF,wEAAwE;AACxE,EAAE;AACF,qFAAqF;AACrF,kEAAkE;AAClE,gFAAgF;AAChF,EAAE;AACF,6FAA6F;AAC7F,8FAA8F;AAC9F,wBAAwB;AACxB,EAAE;AACF,+EAA+E;AAC/E,yFAAyF;AACzF,sFAAsF;AACtF,uFAAuF;AACvF,+CAA+C;AAC/C,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,EAAE;AACF,uFAAuF;AACvF,wEAAwE;AACxE,EAAE;AACF,qFAAqF;AACrF,kEAAkE;AAClE,gFAAgF;AAChF,EAAE;AACF,6FAA6F;AAC7F,8FAA8F;AAC9F,wBAAwB;AACxB,EAAE;AACF,+EAA+E;AAC/E,yFAAyF;AACzF,sFAAsF;AACtF,uFAAuF;AACvF,+CAA+C;AAC/C,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type LoginRequest } from "./login.js";
|
|
2
|
+
/**
|
|
3
|
+
* The label the transaction fingerprint's digest is computed under (docs/login.md §5.3). It is
|
|
4
|
+
* not an RFC 8032 context: nothing is signed with it, and no login proof's bytes are ever a
|
|
5
|
+
* fingerprint's input or the other way round.
|
|
6
|
+
*/
|
|
7
|
+
export declare const FINGERPRINT_DOMAIN = "archon-login-fingerprint/1";
|
|
8
|
+
/**
|
|
9
|
+
* The login's transaction fingerprint (docs/login.md §5.3), what a person compares before
|
|
10
|
+
* approving: the page that began the login computes it from its own K and the begin response,
|
|
11
|
+
* the CLI from the exact request it is about to sign, and the two agree only if every field the
|
|
12
|
+
* login proof binds — audience, K, id, scope, validity — and the nonce are the same on both
|
|
13
|
+
* sides. It is the first 16 bytes (128 bits) of
|
|
14
|
+
*
|
|
15
|
+
* SHA-256( u16be(len domain) ‖ domain ‖ u16be(len nonce) ‖ nonce ‖ loginBinding(LOGIN_ROLE_LOGIN, audience, req) )
|
|
16
|
+
*
|
|
17
|
+
* with domain `FINGERPRINT_DOMAIN` — an encoding of its own beside the proof's, pinned by
|
|
18
|
+
* vectors/login.json's login_fingerprint family. Throws for everything
|
|
19
|
+
* `loginBinding(LOGIN_ROLE_LOGIN, …)` throws for, and for a nonce shorter than `MIN_NONCE_SIZE`
|
|
20
|
+
* or longer than the u16 prefix allows.
|
|
21
|
+
*/
|
|
22
|
+
export declare function fingerprint(audience: string, req: LoginRequest): Uint8Array;
|
|
23
|
+
/**
|
|
24
|
+
* `fp` as a person reads and compares it (docs/login.md §5.3): its 32 lowercase hex digits in
|
|
25
|
+
* eight groups of four, separated by single ASCII spaces — `7a91 b2c3 d4e5 f607 1829 3a4b 5c6d
|
|
26
|
+
* 7e8f`. The three lanes spell it identically, so the page's rendering and the CLI's can be
|
|
27
|
+
* compared character by character. Throws unless `fp` is exactly 16 bytes.
|
|
28
|
+
*/
|
|
29
|
+
export declare function formatFingerprint(fp: Uint8Array): string;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// The transaction fingerprint a person compares before approving a login (docs/login.md §5.3).
|
|
2
|
+
//
|
|
3
|
+
// The page that began the login computes it from its own K and the begin response, in the
|
|
4
|
+
// browser; the CLI computes it from the exact request it is about to sign. So this module runs
|
|
5
|
+
// anywhere the package does: SHA-256 is @noble/hashes (as in request.ts), never node:crypto.
|
|
6
|
+
import { sha256 } from "@noble/hashes/sha2.js";
|
|
7
|
+
import { LOGIN_MAX_FIELD_SIZE, LOGIN_ROLE_LOGIN, loginBinding } from "./login.js";
|
|
8
|
+
import { MIN_NONCE_SIZE } from "./possession.js";
|
|
9
|
+
/**
|
|
10
|
+
* The label the transaction fingerprint's digest is computed under (docs/login.md §5.3). It is
|
|
11
|
+
* not an RFC 8032 context: nothing is signed with it, and no login proof's bytes are ever a
|
|
12
|
+
* fingerprint's input or the other way round.
|
|
13
|
+
*/
|
|
14
|
+
export const FINGERPRINT_DOMAIN = "archon-login-fingerprint/1";
|
|
15
|
+
const DOMAIN_BYTES = new TextEncoder().encode(FINGERPRINT_DOMAIN);
|
|
16
|
+
/**
|
|
17
|
+
* The login's transaction fingerprint (docs/login.md §5.3), what a person compares before
|
|
18
|
+
* approving: the page that began the login computes it from its own K and the begin response,
|
|
19
|
+
* the CLI from the exact request it is about to sign, and the two agree only if every field the
|
|
20
|
+
* login proof binds — audience, K, id, scope, validity — and the nonce are the same on both
|
|
21
|
+
* sides. It is the first 16 bytes (128 bits) of
|
|
22
|
+
*
|
|
23
|
+
* SHA-256( u16be(len domain) ‖ domain ‖ u16be(len nonce) ‖ nonce ‖ loginBinding(LOGIN_ROLE_LOGIN, audience, req) )
|
|
24
|
+
*
|
|
25
|
+
* with domain `FINGERPRINT_DOMAIN` — an encoding of its own beside the proof's, pinned by
|
|
26
|
+
* vectors/login.json's login_fingerprint family. Throws for everything
|
|
27
|
+
* `loginBinding(LOGIN_ROLE_LOGIN, …)` throws for, and for a nonce shorter than `MIN_NONCE_SIZE`
|
|
28
|
+
* or longer than the u16 prefix allows.
|
|
29
|
+
*/
|
|
30
|
+
export function fingerprint(audience, req) {
|
|
31
|
+
const binding = loginBinding(LOGIN_ROLE_LOGIN, audience, req);
|
|
32
|
+
if (req.nonce.length < MIN_NONCE_SIZE || req.nonce.length > LOGIN_MAX_FIELD_SIZE) {
|
|
33
|
+
throw new Error(`login: nonce is ${req.nonce.length} bytes, want ${MIN_NONCE_SIZE}..=${LOGIN_MAX_FIELD_SIZE}`);
|
|
34
|
+
}
|
|
35
|
+
const input = new Uint8Array(2 + DOMAIN_BYTES.length + 2 + req.nonce.length + binding.length);
|
|
36
|
+
let at = putField(input, 0, DOMAIN_BYTES);
|
|
37
|
+
at = putField(input, at, req.nonce);
|
|
38
|
+
input.set(binding, at);
|
|
39
|
+
return sha256(input).slice(0, 16);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* `fp` as a person reads and compares it (docs/login.md §5.3): its 32 lowercase hex digits in
|
|
43
|
+
* eight groups of four, separated by single ASCII spaces — `7a91 b2c3 d4e5 f607 1829 3a4b 5c6d
|
|
44
|
+
* 7e8f`. The three lanes spell it identically, so the page's rendering and the CLI's can be
|
|
45
|
+
* compared character by character. Throws unless `fp` is exactly 16 bytes.
|
|
46
|
+
*/
|
|
47
|
+
export function formatFingerprint(fp) {
|
|
48
|
+
if (fp.length !== 16)
|
|
49
|
+
throw new Error(`login: fingerprint is ${fp.length} bytes, want 16`);
|
|
50
|
+
const groups = [];
|
|
51
|
+
for (let i = 0; i < 16; i += 2) {
|
|
52
|
+
groups.push(fp[i].toString(16).padStart(2, "0") + fp[i + 1].toString(16).padStart(2, "0"));
|
|
53
|
+
}
|
|
54
|
+
return groups.join(" ");
|
|
55
|
+
}
|
|
56
|
+
/** Writes u16be(len field) ‖ field at `at`; returns the new offset. */
|
|
57
|
+
function putField(out, at, field) {
|
|
58
|
+
out[at++] = (field.length >> 8) & 0xff;
|
|
59
|
+
out[at++] = field.length & 0xff;
|
|
60
|
+
out.set(field, at);
|
|
61
|
+
return at + field.length;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=login-fingerprint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login-fingerprint.js","sourceRoot":"","sources":["../../src/login-fingerprint.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,EAAE;AACF,0FAA0F;AAC1F,+FAA+F;AAC/F,6FAA6F;AAC7F,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE/C,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,YAAY,EAAqB,MAAM,YAAY,CAAC;AACrG,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,4BAA4B,CAAC;AAE/D,MAAM,YAAY,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAElE;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,WAAW,CAAC,QAAgB,EAAE,GAAiB;IAC7D,MAAM,OAAO,GAAG,YAAY,CAAC,gBAAgB,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC9D,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,cAAc,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,oBAAoB,EAAE,CAAC;QACjF,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,CAAC,KAAK,CAAC,MAAM,gBAAgB,cAAc,MAAM,oBAAoB,EAAE,CAAC,CAAC;IACjH,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,CAAC,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9F,IAAI,EAAE,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC;IAC1C,EAAE,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;IACpC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACvB,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACpC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAAc;IAC9C,IAAI,EAAE,CAAC,MAAM,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,EAAE,CAAC,MAAM,iBAAiB,CAAC,CAAC;IAC3F,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/F,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED,uEAAuE;AACvE,SAAS,QAAQ,CAAC,GAAe,EAAE,EAAU,EAAE,KAAiB;IAC9D,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;IACvC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;IAChC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACnB,OAAO,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC;AAC3B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bitspark/archon-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "archon-sdk: proof of possession and the signed envelope, one layer above the identity floor. Deterministic given its inputs; no RNG, no clock, no socket.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"test": "tsc -p tsconfig.json && node --test dist/test/*.test.js"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@bitspark/archon": "^0.
|
|
25
|
+
"@bitspark/archon": "^0.15.0",
|
|
26
26
|
"@noble/hashes": "^2.2.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|