@pulse-compute/crypto 0.0.0 → 1.0.0-beta.2
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 +138 -3
- package/as/pulse-hmac-as.ts +344 -0
- package/dist/contracts.d.ts +198 -0
- package/dist/contracts.d.ts.map +1 -0
- package/dist/contracts.js +149 -0
- package/dist/contracts.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +52 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/data.d.ts +10 -0
- package/dist/internal/data.d.ts.map +1 -0
- package/dist/internal/data.js +41 -0
- package/dist/internal/data.js.map +1 -0
- package/dist/internal/realization.d.ts +11 -0
- package/dist/internal/realization.d.ts.map +1 -0
- package/dist/internal/realization.js +140 -0
- package/dist/internal/realization.js.map +1 -0
- package/dist/internal/verification.d.ts +67 -0
- package/dist/internal/verification.d.ts.map +1 -0
- package/dist/internal/verification.js +273 -0
- package/dist/internal/verification.js.map +1 -0
- package/package.json +38 -6
- package/pulsewasm.native.cjs +127 -0
- package/src/provider.cjs +43 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import { CRYPTO_RESOURCE_LIMITS, CRYPTO_VERIFICATION_STATUSES, } from '../contracts.js';
|
|
2
|
+
import { copyBytes, exactDataProperties, isOrdinaryObject, ownDataProperty, } from './data.js';
|
|
3
|
+
const REQUEST_KEYS = new Set(['algorithm', 'key', 'data', 'tag']);
|
|
4
|
+
const KEY_KEYS = new Set(['type', 'bytes']);
|
|
5
|
+
const SIGNATURE_REQUEST_KEYS = new Set(['algorithm', 'key', 'data', 'signature']);
|
|
6
|
+
const P256_KEY_KEYS = new Set(['type', 'bytes']);
|
|
7
|
+
const JOSE_REQUEST_KEYS = new Set(['key', 'data', 'signature']);
|
|
8
|
+
const JOSE_KEY_KEYS = new Set(['x', 'y']);
|
|
9
|
+
const BASE64URL = /^[A-Za-z0-9_-]+$/;
|
|
10
|
+
const P256_ORDER = Uint8Array.from([
|
|
11
|
+
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
|
12
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
13
|
+
0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84,
|
|
14
|
+
0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51,
|
|
15
|
+
]);
|
|
16
|
+
const RESULTS = Object.freeze(Object.fromEntries(CRYPTO_VERIFICATION_STATUSES.map((status) => [
|
|
17
|
+
status,
|
|
18
|
+
Object.freeze({ status }),
|
|
19
|
+
])));
|
|
20
|
+
export function verificationResult(status) {
|
|
21
|
+
return RESULTS[status];
|
|
22
|
+
}
|
|
23
|
+
function invalidInput() {
|
|
24
|
+
return Object.freeze({
|
|
25
|
+
ok: false,
|
|
26
|
+
result: verificationResult('invalid-input'),
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
function invalidKey() {
|
|
30
|
+
return Object.freeze({
|
|
31
|
+
ok: false,
|
|
32
|
+
result: verificationResult('invalid-key'),
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function invalidSignatureInput() {
|
|
36
|
+
return Object.freeze({
|
|
37
|
+
ok: false,
|
|
38
|
+
result: verificationResult('invalid-input'),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function invalidSignatureKey() {
|
|
42
|
+
return Object.freeze({
|
|
43
|
+
ok: false,
|
|
44
|
+
result: verificationResult('invalid-key'),
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function compareBigEndian(left, right) {
|
|
48
|
+
for (let index = 0; index < left.byteLength; index += 1) {
|
|
49
|
+
if (left[index] < right[index])
|
|
50
|
+
return -1;
|
|
51
|
+
if (left[index] > right[index])
|
|
52
|
+
return 1;
|
|
53
|
+
}
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
56
|
+
function validP256Scalar(value) {
|
|
57
|
+
let nonZero = false;
|
|
58
|
+
for (const byte of value)
|
|
59
|
+
nonZero ||= byte !== 0;
|
|
60
|
+
return nonZero && compareBigEndian(value, P256_ORDER) < 0;
|
|
61
|
+
}
|
|
62
|
+
function validEs256Signature(signature) {
|
|
63
|
+
return signature.byteLength === CRYPTO_RESOURCE_LIMITS.es256SignatureBytes
|
|
64
|
+
&& validP256Scalar(signature.subarray(0, 32))
|
|
65
|
+
&& validP256Scalar(signature.subarray(32, 64));
|
|
66
|
+
}
|
|
67
|
+
function decodeCanonicalBase64url(value, expectedBytes) {
|
|
68
|
+
if (typeof value !== 'string'
|
|
69
|
+
|| value.length === 0
|
|
70
|
+
|| value.includes('=')
|
|
71
|
+
|| !BASE64URL.test(value)
|
|
72
|
+
|| value.length % 4 === 1)
|
|
73
|
+
return undefined;
|
|
74
|
+
const padded = value.replace(/-/g, '+').replace(/_/g, '/')
|
|
75
|
+
+ '='.repeat((4 - value.length % 4) % 4);
|
|
76
|
+
let binary;
|
|
77
|
+
try {
|
|
78
|
+
binary = atob(padded);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
const bytes = Uint8Array.from(binary, (character) => character.charCodeAt(0));
|
|
84
|
+
if (bytes.byteLength !== expectedBytes)
|
|
85
|
+
return undefined;
|
|
86
|
+
let canonical = '';
|
|
87
|
+
for (const byte of bytes)
|
|
88
|
+
canonical += String.fromCharCode(byte);
|
|
89
|
+
canonical = btoa(canonical)
|
|
90
|
+
.replace(/\+/g, '-')
|
|
91
|
+
.replace(/\//g, '_')
|
|
92
|
+
.replace(/=+$/u, '');
|
|
93
|
+
return canonical === value ? bytes : undefined;
|
|
94
|
+
}
|
|
95
|
+
export function normalizeMacVerifyRequest(value) {
|
|
96
|
+
if (!isOrdinaryObject(value) || !exactDataProperties(value, REQUEST_KEYS)) {
|
|
97
|
+
return invalidInput();
|
|
98
|
+
}
|
|
99
|
+
const algorithm = ownDataProperty(value, 'algorithm').value;
|
|
100
|
+
if (algorithm !== 'HS256')
|
|
101
|
+
return invalidInput();
|
|
102
|
+
const keyValue = ownDataProperty(value, 'key').value;
|
|
103
|
+
if (!isOrdinaryObject(keyValue) || !exactDataProperties(keyValue, KEY_KEYS)) {
|
|
104
|
+
return invalidKey();
|
|
105
|
+
}
|
|
106
|
+
if (ownDataProperty(keyValue, 'type').value !== 'hmac-key-bytes') {
|
|
107
|
+
return invalidKey();
|
|
108
|
+
}
|
|
109
|
+
const keyBytes = copyBytes(ownDataProperty(keyValue, 'bytes').value);
|
|
110
|
+
if (!keyBytes
|
|
111
|
+
|| keyBytes.byteLength < CRYPTO_RESOURCE_LIMITS.hmacKeyBytesMinimum
|
|
112
|
+
|| keyBytes.byteLength > CRYPTO_RESOURCE_LIMITS.hmacKeyBytesMaximum) {
|
|
113
|
+
return invalidKey();
|
|
114
|
+
}
|
|
115
|
+
const data = copyBytes(ownDataProperty(value, 'data').value);
|
|
116
|
+
const tag = copyBytes(ownDataProperty(value, 'tag').value);
|
|
117
|
+
if (!data
|
|
118
|
+
|| data.byteLength > CRYPTO_RESOURCE_LIMITS.macDataBytesMaximum
|
|
119
|
+
|| !tag
|
|
120
|
+
|| tag.byteLength !== CRYPTO_RESOURCE_LIMITS.hs256TagBytes) {
|
|
121
|
+
return invalidInput();
|
|
122
|
+
}
|
|
123
|
+
return Object.freeze({
|
|
124
|
+
ok: true,
|
|
125
|
+
request: Object.freeze({
|
|
126
|
+
algorithm,
|
|
127
|
+
key: Object.freeze({
|
|
128
|
+
type: 'hmac-key-bytes',
|
|
129
|
+
bytes: keyBytes,
|
|
130
|
+
}),
|
|
131
|
+
data,
|
|
132
|
+
tag,
|
|
133
|
+
}),
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
export function normalizeSignatureVerifyRequest(value) {
|
|
137
|
+
if (!isOrdinaryObject(value)
|
|
138
|
+
|| !exactDataProperties(value, SIGNATURE_REQUEST_KEYS))
|
|
139
|
+
return invalidSignatureInput();
|
|
140
|
+
if (ownDataProperty(value, 'algorithm').value !== 'ES256') {
|
|
141
|
+
return invalidSignatureInput();
|
|
142
|
+
}
|
|
143
|
+
const keyValue = ownDataProperty(value, 'key').value;
|
|
144
|
+
if (!isOrdinaryObject(keyValue)
|
|
145
|
+
|| !exactDataProperties(keyValue, P256_KEY_KEYS)
|
|
146
|
+
|| ownDataProperty(keyValue, 'type').value !== 'p256-public-key-bytes')
|
|
147
|
+
return invalidSignatureKey();
|
|
148
|
+
const keyBytes = copyBytes(ownDataProperty(keyValue, 'bytes').value);
|
|
149
|
+
if (!keyBytes
|
|
150
|
+
|| keyBytes.byteLength !== CRYPTO_RESOURCE_LIMITS.es256PublicKeyBytes)
|
|
151
|
+
return invalidSignatureKey();
|
|
152
|
+
const data = copyBytes(ownDataProperty(value, 'data').value);
|
|
153
|
+
const signature = copyBytes(ownDataProperty(value, 'signature').value);
|
|
154
|
+
if (!data
|
|
155
|
+
|| data.byteLength > CRYPTO_RESOURCE_LIMITS.es256SigningInputBytesMaximum
|
|
156
|
+
|| !signature
|
|
157
|
+
|| !validEs256Signature(signature)) {
|
|
158
|
+
keyBytes.fill(0);
|
|
159
|
+
return invalidSignatureInput();
|
|
160
|
+
}
|
|
161
|
+
return Object.freeze({
|
|
162
|
+
ok: true,
|
|
163
|
+
request: Object.freeze({
|
|
164
|
+
algorithm: 'ES256',
|
|
165
|
+
key: Object.freeze({
|
|
166
|
+
type: 'p256-public-key-bytes',
|
|
167
|
+
bytes: keyBytes,
|
|
168
|
+
}),
|
|
169
|
+
data,
|
|
170
|
+
signature,
|
|
171
|
+
}),
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
export function normalizeEs256JoseVerifyRequest(value) {
|
|
175
|
+
if (!isOrdinaryObject(value) || !exactDataProperties(value, JOSE_REQUEST_KEYS)) {
|
|
176
|
+
return invalidSignatureInput();
|
|
177
|
+
}
|
|
178
|
+
const keyValue = ownDataProperty(value, 'key').value;
|
|
179
|
+
if (!isOrdinaryObject(keyValue) || !exactDataProperties(keyValue, JOSE_KEY_KEYS)) {
|
|
180
|
+
return invalidSignatureKey();
|
|
181
|
+
}
|
|
182
|
+
const normalizedKey = normalizeP256PublicKeyCoordinates(keyValue);
|
|
183
|
+
if (!normalizedKey.ok)
|
|
184
|
+
return normalizedKey;
|
|
185
|
+
const signature = decodeCanonicalBase64url(ownDataProperty(value, 'signature').value, CRYPTO_RESOURCE_LIMITS.es256SignatureBytes);
|
|
186
|
+
if (!signature || !validEs256Signature(signature)) {
|
|
187
|
+
normalizedKey.key.bytes.fill(0);
|
|
188
|
+
return invalidSignatureInput();
|
|
189
|
+
}
|
|
190
|
+
const data = copyBytes(ownDataProperty(value, 'data').value);
|
|
191
|
+
if (!data
|
|
192
|
+
|| data.byteLength > CRYPTO_RESOURCE_LIMITS.es256SigningInputBytesMaximum) {
|
|
193
|
+
normalizedKey.key.bytes.fill(0);
|
|
194
|
+
return invalidSignatureInput();
|
|
195
|
+
}
|
|
196
|
+
return Object.freeze({
|
|
197
|
+
ok: true,
|
|
198
|
+
request: Object.freeze({
|
|
199
|
+
algorithm: 'ES256',
|
|
200
|
+
key: normalizedKey.key,
|
|
201
|
+
data,
|
|
202
|
+
signature,
|
|
203
|
+
}),
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
export function normalizeP256PublicKeyCoordinates(value) {
|
|
207
|
+
if (!isOrdinaryObject(value) || !exactDataProperties(value, JOSE_KEY_KEYS)) {
|
|
208
|
+
return Object.freeze({
|
|
209
|
+
ok: false,
|
|
210
|
+
result: verificationResult('invalid-key'),
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
const x = decodeCanonicalBase64url(ownDataProperty(value, 'x').value, 32);
|
|
214
|
+
const y = decodeCanonicalBase64url(ownDataProperty(value, 'y').value, 32);
|
|
215
|
+
if (!x || !y) {
|
|
216
|
+
if (x)
|
|
217
|
+
x.fill(0);
|
|
218
|
+
if (y)
|
|
219
|
+
y.fill(0);
|
|
220
|
+
return Object.freeze({
|
|
221
|
+
ok: false,
|
|
222
|
+
result: verificationResult('invalid-key'),
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
const keyBytes = new Uint8Array(CRYPTO_RESOURCE_LIMITS.es256PublicKeyBytes);
|
|
226
|
+
keyBytes.set(x, 0);
|
|
227
|
+
keyBytes.set(y, 32);
|
|
228
|
+
x.fill(0);
|
|
229
|
+
y.fill(0);
|
|
230
|
+
return Object.freeze({
|
|
231
|
+
ok: true,
|
|
232
|
+
key: Object.freeze({
|
|
233
|
+
type: 'p256-public-key-bytes',
|
|
234
|
+
bytes: keyBytes,
|
|
235
|
+
}),
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
export function normalizeVerificationResult(value) {
|
|
239
|
+
if (!isOrdinaryObject(value) || !exactDataProperties(value, new Set(['status']))) {
|
|
240
|
+
return verificationResult('realization-failure');
|
|
241
|
+
}
|
|
242
|
+
const status = ownDataProperty(value, 'status').value;
|
|
243
|
+
if (typeof status !== 'string'
|
|
244
|
+
|| !CRYPTO_VERIFICATION_STATUSES.includes(status)) {
|
|
245
|
+
return verificationResult('realization-failure');
|
|
246
|
+
}
|
|
247
|
+
return verificationResult(status);
|
|
248
|
+
}
|
|
249
|
+
export function redactMacVerifyRequest(request) {
|
|
250
|
+
return Object.freeze({
|
|
251
|
+
algorithm: request.algorithm,
|
|
252
|
+
key: Object.freeze({
|
|
253
|
+
type: 'hmac-key-bytes',
|
|
254
|
+
compatibleAlgorithms: Object.freeze(['HS256']),
|
|
255
|
+
identity: '[redacted]',
|
|
256
|
+
}),
|
|
257
|
+
data: '[redacted]',
|
|
258
|
+
tag: '[redacted]',
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
export function redactSignatureVerifyRequest(request) {
|
|
262
|
+
return Object.freeze({
|
|
263
|
+
algorithm: request.algorithm,
|
|
264
|
+
key: Object.freeze({
|
|
265
|
+
type: 'p256-public-key-bytes',
|
|
266
|
+
compatibleAlgorithms: Object.freeze(['ES256']),
|
|
267
|
+
identity: '[redacted]',
|
|
268
|
+
}),
|
|
269
|
+
data: '[redacted]',
|
|
270
|
+
signature: '[redacted]',
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
//# sourceMappingURL=verification.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verification.js","sourceRoot":"","sources":["../../src/internal/verification.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,16 +1,48 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pulse-compute/crypto",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "Inert bootstrap placeholder for @pulse-compute/crypto.",
|
|
3
|
+
"version": "1.0.0-beta.2",
|
|
5
4
|
"license": "Apache-2.0",
|
|
5
|
+
"engines": {
|
|
6
|
+
"node": "^22.14.0 || ^24.0.0"
|
|
7
|
+
},
|
|
8
|
+
"description": "Provider-neutral cryptographic verification contracts for Pulse.",
|
|
9
|
+
"type": "module",
|
|
10
|
+
"sideEffects": false,
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.js",
|
|
15
|
+
"default": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./pulsewasm-native": "./pulsewasm.native.cjs",
|
|
18
|
+
"./provider": "./src/provider.cjs"
|
|
19
|
+
},
|
|
6
20
|
"files": [
|
|
21
|
+
"as",
|
|
22
|
+
"dist",
|
|
23
|
+
"pulsewasm.native.cjs",
|
|
7
24
|
"README.md",
|
|
25
|
+
"src/provider.cjs",
|
|
8
26
|
"LICENSE",
|
|
9
27
|
"NOTICE"
|
|
10
28
|
],
|
|
11
29
|
"publishConfig": {
|
|
12
|
-
"access": "public"
|
|
13
|
-
|
|
14
|
-
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "git+https://github.com/pulse-compute/pulse.git",
|
|
35
|
+
"directory": "packages/crypto"
|
|
36
|
+
},
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/pulse-compute/pulse/issues"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://pulsecompute.io/v1.0.0-beta.2/packages/crypto/",
|
|
41
|
+
"main": "./dist/index.js",
|
|
42
|
+
"types": "./dist/index.d.ts",
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "tsc -b",
|
|
45
|
+
"test": "corepack pnpm --dir ../.. exec vitest run packages/crypto/test",
|
|
46
|
+
"test:types": "tsc -p tsconfig.types.json --noEmit"
|
|
15
47
|
}
|
|
16
|
-
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const crypto = require('node:crypto');
|
|
4
|
+
const fs = require('node:fs');
|
|
5
|
+
const path = require('node:path');
|
|
6
|
+
const packageManifest = require('./package.json');
|
|
7
|
+
|
|
8
|
+
const CRYPTO_GUEST_SOURCE_CONTRACT_VERSION = 'pulse.crypto-guest-source.v1';
|
|
9
|
+
const GUEST_UNIT_CONTRIBUTION_VERSION = 'pulse.guest-unit-contribution.v1';
|
|
10
|
+
const sourceRelativeFile = 'as/pulse-hmac-as.ts';
|
|
11
|
+
const sourceFile = path.join(__dirname, sourceRelativeFile);
|
|
12
|
+
|
|
13
|
+
function sha256(value) {
|
|
14
|
+
return crypto.createHash('sha256').update(value).digest('hex');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function pulseHmacAssemblyScriptSource(algorithm = 'HS256') {
|
|
18
|
+
if (!['HS256', 'SHA-256', 'HMAC-SHA256'].includes(algorithm)) throw new TypeError('Unsupported Crypto guest-source algorithm.');
|
|
19
|
+
const source = fs.readFileSync(sourceFile, 'utf8');
|
|
20
|
+
return Object.freeze({
|
|
21
|
+
version: CRYPTO_GUEST_SOURCE_CONTRACT_VERSION,
|
|
22
|
+
id: 'pulse-hmac-as',
|
|
23
|
+
owner: '@pulse-compute/crypto',
|
|
24
|
+
packageVersion: packageManifest.version,
|
|
25
|
+
realization: 'guest-source:pulse-hmac-as',
|
|
26
|
+
kind: 'guest-source',
|
|
27
|
+
backend: 'pulse-hmac-as',
|
|
28
|
+
backendVersion: 'pulse-hmac-as.v1',
|
|
29
|
+
algorithm,
|
|
30
|
+
language: 'assemblyscript',
|
|
31
|
+
license: 'Apache-2.0',
|
|
32
|
+
origin: 'package-source',
|
|
33
|
+
sourceIncluded: true,
|
|
34
|
+
provenance: Object.freeze([
|
|
35
|
+
'NIST FIPS 180-4',
|
|
36
|
+
'RFC 2104',
|
|
37
|
+
'RFC 4231'
|
|
38
|
+
]),
|
|
39
|
+
sourceFile: sourceRelativeFile,
|
|
40
|
+
source,
|
|
41
|
+
sourceBytes: Buffer.byteLength(source),
|
|
42
|
+
sourceSha256: sha256(source),
|
|
43
|
+
imports: Object.freeze([]),
|
|
44
|
+
exports: Object.freeze([
|
|
45
|
+
'pulse_crypto_hs256_verify',
|
|
46
|
+
'pulse_crypto_sha256_digest',
|
|
47
|
+
'pulse_crypto_bytes_frame_v1',
|
|
48
|
+
'pulse_crypto_sha256_bytes_v1',
|
|
49
|
+
'pulse_crypto_hmac_sha256_bytes_v1'
|
|
50
|
+
]),
|
|
51
|
+
resourceLimits: Object.freeze({
|
|
52
|
+
hmacKeyBytesMinimum: 32,
|
|
53
|
+
hmacKeyBytesMaximum: 4 * 1024,
|
|
54
|
+
macDataBytesMaximum: 1024 * 1024,
|
|
55
|
+
hs256TagBytes: 32,
|
|
56
|
+
byteOperationKeyBytesMaximum: 8192,
|
|
57
|
+
byteOperationDataBytesMaximum: 32768,
|
|
58
|
+
byteOperationOutputBytes: 32,
|
|
59
|
+
byteOperationFrameBytes: 40992
|
|
60
|
+
}),
|
|
61
|
+
resultCodes: Object.freeze({
|
|
62
|
+
valid: 1,
|
|
63
|
+
invalidAuthenticator: 0,
|
|
64
|
+
invalidKey: -1,
|
|
65
|
+
invalidInput: -2,
|
|
66
|
+
realizationFailure: -3
|
|
67
|
+
}),
|
|
68
|
+
comparison: Object.freeze({
|
|
69
|
+
mode: 'constant-time-full-tag-scan',
|
|
70
|
+
bytes: 32,
|
|
71
|
+
earlyMismatchReturn: false
|
|
72
|
+
}),
|
|
73
|
+
automaticFallback: false
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function bindNativeDigestMac(moduleExports) {
|
|
78
|
+
const memory = moduleExports && moduleExports.memory;
|
|
79
|
+
const names = ['pulse_crypto_bytes_frame_v1', 'pulse_crypto_sha256_bytes_v1', 'pulse_crypto_hmac_sha256_bytes_v1'];
|
|
80
|
+
if (!(memory instanceof WebAssembly.Memory) || names.some((name) => typeof moduleExports[name] !== 'function')) {
|
|
81
|
+
throw new TypeError('Native Crypto digest/MAC exports are unavailable.');
|
|
82
|
+
}
|
|
83
|
+
const frameBytes = 8192 + 32768 + 32;
|
|
84
|
+
function run(data, key) {
|
|
85
|
+
if (!(data instanceof Uint8Array) || data.length > 32768
|
|
86
|
+
|| (key !== undefined && (!(key instanceof Uint8Array) || key.length > 8192))) {
|
|
87
|
+
throw new TypeError('Native Crypto digest/MAC input exceeds its byte contract.');
|
|
88
|
+
}
|
|
89
|
+
const pointer = moduleExports.pulse_crypto_bytes_frame_v1() >>> 0;
|
|
90
|
+
if (pointer + frameBytes > memory.buffer.byteLength) throw new TypeError('Native Crypto frame is outside memory.');
|
|
91
|
+
const dataPointer = pointer + 8192;
|
|
92
|
+
const outputPointer = dataPointer + 32768;
|
|
93
|
+
try {
|
|
94
|
+
const view = new Uint8Array(memory.buffer);
|
|
95
|
+
view.set(data, dataPointer);
|
|
96
|
+
if (key !== undefined) view.set(key, pointer);
|
|
97
|
+
const code = key === undefined
|
|
98
|
+
? moduleExports.pulse_crypto_sha256_bytes_v1(dataPointer, data.length, outputPointer, 32)
|
|
99
|
+
: moduleExports.pulse_crypto_hmac_sha256_bytes_v1(pointer, key.length, dataPointer, data.length, outputPointer, 32);
|
|
100
|
+
if (code !== 1) throw new TypeError('Native Crypto digest/MAC realization failed.');
|
|
101
|
+
return new Uint8Array(memory.buffer, outputPointer, 32).slice();
|
|
102
|
+
} finally {
|
|
103
|
+
// The Wasm allocator can grow memory while hashing: acquire a fresh view.
|
|
104
|
+
new Uint8Array(memory.buffer, pointer, frameBytes).fill(0);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return Object.freeze({ sha256: (data) => run(data), hmacSha256: (key, data) => run(data, key) });
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function pulseEs256GuestUnit() {
|
|
111
|
+
return Object.freeze({
|
|
112
|
+
version: GUEST_UNIT_CONTRIBUTION_VERSION,
|
|
113
|
+
id: 'pulse.crypto.es256.rustcrypto-p256.v1',
|
|
114
|
+
manifest: './guests/es256-rustcrypto/pulse.guest-unit.json',
|
|
115
|
+
owner: packageManifest.name,
|
|
116
|
+
packageVersion: packageManifest.version,
|
|
117
|
+
origin: 'package-prebuilt'
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
module.exports = Object.freeze({
|
|
122
|
+
CRYPTO_GUEST_SOURCE_CONTRACT_VERSION,
|
|
123
|
+
GUEST_UNIT_CONTRIBUTION_VERSION,
|
|
124
|
+
pulseHmacAssemblyScriptSource,
|
|
125
|
+
bindNativeDigestMac,
|
|
126
|
+
pulseEs256GuestUnit
|
|
127
|
+
});
|
package/src/provider.cjs
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Trusted provider byte-output seam. JWT verification keeps its own key limits.
|
|
4
|
+
const IMPLEMENTATIONS = Object.freeze({
|
|
5
|
+
'SHA-256': 'webcrypto.subtle.sha-256-bytes.v1',
|
|
6
|
+
'HMAC-SHA256': 'webcrypto.subtle.hmac-sha-256-bytes.v1'
|
|
7
|
+
});
|
|
8
|
+
function snapshot(value, maximum) {
|
|
9
|
+
if (!(value instanceof Uint8Array) || value.byteLength > maximum) throw new TypeError('Crypto byte input is outside its bound.');
|
|
10
|
+
return new Uint8Array(value);
|
|
11
|
+
}
|
|
12
|
+
function result(value) {
|
|
13
|
+
if (!(value instanceof ArrayBuffer) || value.byteLength !== 32) throw new TypeError('Crypto byte output is invalid.');
|
|
14
|
+
return new Uint8Array(value);
|
|
15
|
+
}
|
|
16
|
+
function bindJavascriptDigestMac(algorithms, subtle = globalThis.crypto && globalThis.crypto.subtle) {
|
|
17
|
+
if (!Array.isArray(algorithms) || new Set(algorithms).size !== algorithms.length || algorithms.some((name) => !Object.hasOwn(IMPLEMENTATIONS, name))) throw new TypeError('Crypto requires explicit supported byte algorithms.');
|
|
18
|
+
if (!subtle || algorithms.includes('SHA-256') && typeof subtle.digest !== 'function'
|
|
19
|
+
|| algorithms.includes('HMAC-SHA256') && (typeof subtle.sign !== 'function' || typeof subtle.importKey !== 'function')) throw new TypeError('Selected Web Crypto byte realization is unavailable.');
|
|
20
|
+
const bytes = {};
|
|
21
|
+
if (algorithms.includes('SHA-256')) bytes.sha256 = async (input) => {
|
|
22
|
+
const data = snapshot(input, 32768);
|
|
23
|
+
try { return result(await subtle.digest({ name: 'SHA-256' }, data)); }
|
|
24
|
+
finally { data.fill(0); }
|
|
25
|
+
};
|
|
26
|
+
if (algorithms.includes('HMAC-SHA256')) bytes.hmacSha256 = async (keyInput, input) => {
|
|
27
|
+
let key = snapshot(keyInput, 8192);
|
|
28
|
+
let data;
|
|
29
|
+
try {
|
|
30
|
+
data = snapshot(input, 32768);
|
|
31
|
+
// HMAC pads an empty key to a zero block (RFC 2104). Web Crypto rejects
|
|
32
|
+
// a zero-length import; the equivalent padded block retains Native parity.
|
|
33
|
+
if (key.length === 0) key = new Uint8Array(64);
|
|
34
|
+
const imported = await subtle.importKey('raw', key, { name: 'HMAC', hash: 'SHA-256', length: key.length * 8 }, false, ['sign']);
|
|
35
|
+
return result(await subtle.sign({ name: 'HMAC' }, imported, data));
|
|
36
|
+
} finally { key.fill(0); if (data) data.fill(0); }
|
|
37
|
+
};
|
|
38
|
+
return Object.freeze({ bytes: Object.freeze(bytes), realization: Object.freeze({
|
|
39
|
+
target: 'javascript', automaticFallback: false,
|
|
40
|
+
algorithms: Object.freeze(algorithms.map((algorithm) => Object.freeze({ algorithm, realization: 'runtime-builtin', implementation: IMPLEMENTATIONS[algorithm], available: true, automaticFallback: false })))
|
|
41
|
+
}) });
|
|
42
|
+
}
|
|
43
|
+
module.exports = Object.freeze({ IMPLEMENTATIONS, bindJavascriptDigestMac });
|