@reallyme/crypto 0.3.6 → 0.3.7
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/LICENSE +26 -0
- package/README.md +7 -25
- package/dist/aead.js +1 -1
- package/dist/aesKw.js +1 -1
- package/dist/algorithms.js +1 -1
- package/dist/argon2id.js +1 -1
- package/dist/bip340Schnorr.js +11 -2
- package/dist/cryptoFacade.js +1 -1
- package/dist/digest.js +9 -1
- package/dist/ed25519.js +10 -2
- package/dist/encodeEcdsaDer.js +1 -1
- package/dist/errors.js +1 -1
- package/dist/hkdf.js +5 -1
- package/dist/hmac.js +12 -3
- package/dist/hpke.js +1 -1
- package/dist/index.js +1 -1
- package/dist/jwaConcatKdf.js +6 -1
- package/dist/jwk.js +1 -1
- package/dist/kmac.js +1 -1
- package/dist/memory.js +1 -1
- package/dist/mlDsa.js +1 -1
- package/dist/mlKem.js +1 -1
- package/dist/operationResponse.js +1 -1
- package/dist/p256Ecdh.js +7 -2
- package/dist/p256Ecdsa.js +10 -2
- package/dist/p384Ecdh.js +7 -2
- package/dist/p384Ecdsa.js +10 -2
- package/dist/p521Ecdh.js +7 -2
- package/dist/p521Ecdsa.js +10 -2
- package/dist/pbkdf2.js +4 -1
- package/dist/proto/generated/reallyme/crypto/v1/crypto_pb.js +1 -1
- package/dist/proto.js +1 -1
- package/dist/providerCatalog.js +1 -1
- package/dist/rsa.js +1 -1
- package/dist/secp256k1.js +10 -2
- package/dist/slhDsa.js +1 -1
- package/dist/validateBytes.d.ts +1 -1
- package/dist/validateBytes.js +20 -4
- package/dist/wasm/LICENSE +26 -0
- package/dist/wasm/reallyme_crypto_wasm_bg.wasm +0 -0
- package/dist/wasmModuleTypes.js +1 -1
- package/dist/wasmProvider.js +1 -1
- package/dist/x25519.js +7 -2
- package/dist/xWing.js +1 -1
- package/package.json +3 -3
package/LICENSE
CHANGED
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
ReallyMe Crypto is licensed, at your option, under either the MIT License or
|
|
2
|
+
the Apache License, Version 2.0. The full text of both licenses follows.
|
|
3
|
+
Third-party components retain their own licenses and notices.
|
|
4
|
+
|
|
5
|
+
MIT License
|
|
6
|
+
|
|
7
|
+
Copyright © 2026 ReallyMe LLC.
|
|
8
|
+
|
|
9
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
10
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
11
|
+
in the Software without restriction, including without limitation the rights
|
|
12
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
13
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
14
|
+
furnished to do so, subject to the following conditions:
|
|
15
|
+
|
|
16
|
+
The above copyright notice and this permission notice shall be included in all
|
|
17
|
+
copies or substantial portions of the Software.
|
|
18
|
+
|
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
20
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
21
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
22
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
23
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
24
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
25
|
+
SOFTWARE.
|
|
26
|
+
|
|
1
27
|
Apache License
|
|
2
28
|
Version 2.0, January 2004
|
|
3
29
|
http://www.apache.org/licenses/
|
package/README.md
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
3
|
-
|
|
4
|
-
SPDX-License-Identifier: Apache-2.0
|
|
5
3
|
-->
|
|
6
4
|
|
|
7
5
|
# @reallyme/crypto
|
|
8
6
|
|
|
9
7
|
[](https://www.npmjs.com/package/@reallyme/crypto)
|
|
10
|
-
[](https://github.com/reallyme/crypto/blob/main/LICENSE)
|
|
11
9
|
|
|
12
10
|
`@reallyme/crypto` is the TypeScript SDK for ReallyMe Crypto. It provides typed,
|
|
13
11
|
synchronous APIs for Node.js and browsers, with explicit JavaScript and
|
|
@@ -17,16 +15,6 @@ The package shares algorithm identifiers, byte formats, typed failures, and
|
|
|
17
15
|
conformance vectors with the Rust, Swift, Kotlin, and Android SDKs. Availability
|
|
18
16
|
is provider-specific; unsupported routes fail closed.
|
|
19
17
|
|
|
20
|
-
## Why
|
|
21
|
-
|
|
22
|
-
Modern cryptography APIs differ across platforms. Algorithms are exposed
|
|
23
|
-
differently, key formats vary, providers have different capabilities, and error
|
|
24
|
-
behavior is inconsistent.
|
|
25
|
-
|
|
26
|
-
ReallyMe Crypto makes platform differences explicit while preserving a stable
|
|
27
|
-
contract for every supported route. Applications can share protocol logic
|
|
28
|
-
without silently changing cryptographic providers.
|
|
29
|
-
|
|
30
18
|
## Installation
|
|
31
19
|
|
|
32
20
|
```sh
|
|
@@ -187,18 +175,6 @@ created.
|
|
|
187
175
|
Do not move private keys, passwords, plaintext, shared secrets, or derived keys
|
|
188
176
|
through strings or JSON paths.
|
|
189
177
|
|
|
190
|
-
## Features
|
|
191
|
-
|
|
192
|
-
- Platform-agnostic cryptography APIs.
|
|
193
|
-
- Consistent key formats and protocol identifiers.
|
|
194
|
-
- Shared conformance vectors across Rust, Swift, Kotlin, and TypeScript.
|
|
195
|
-
- Native providers where available, WASM-backed implementations where needed.
|
|
196
|
-
- Typed errors and fail-closed verification behavior.
|
|
197
|
-
- Generated protobuf operations, algorithm identifiers, and typed wire errors
|
|
198
|
-
via `@reallyme/crypto/proto`.
|
|
199
|
-
- JWK, multikey, multicodec, HPKE, ML-KEM, ML-DSA, Ed25519, secp256k1, X25519,
|
|
200
|
-
AES-GCM, ChaCha20-Poly1305, and more.
|
|
201
|
-
|
|
202
178
|
## Protobuf Process Boundary
|
|
203
179
|
|
|
204
180
|
`processOperationResponse(request)` accepts one generated binary
|
|
@@ -220,3 +196,9 @@ The complete documentation, provider matrix, protocol contracts, and conformance
|
|
|
220
196
|
specifications are available in the main repository:
|
|
221
197
|
|
|
222
198
|
https://github.com/reallyme/crypto
|
|
199
|
+
|
|
200
|
+
## License
|
|
201
|
+
|
|
202
|
+
Licensed under either the MIT License or the Apache License, Version 2.0,
|
|
203
|
+
at your option. See [LICENSE](https://github.com/reallyme/crypto/blob/main/LICENSE). Third-party components retain
|
|
204
|
+
their own licenses and notices.
|
package/dist/aead.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
5
5
|
import { ensureByteArrayAtMost, ensureBytes, ensureIndependentByteArray, MAX_CRYPTO_INPUT_LENGTH, } from "./validateBytes.js";
|
|
6
6
|
import { requireReallyMeWasmProvider } from "./wasmProvider.js";
|
package/dist/aesKw.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
5
5
|
import { ensureByteArray, ensureBytes, ensureIndependentByteArray, } from "./validateBytes.js";
|
|
6
6
|
import { requireReallyMeWasmProvider } from "./wasmProvider.js";
|
package/dist/algorithms.js
CHANGED
package/dist/argon2id.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
5
5
|
import { ensureByteArrayAtMost, ensureIndependentByteArray, } from "./validateBytes.js";
|
|
6
6
|
import { requireReallyMeWasmProvider } from "./wasmProvider.js";
|
package/dist/bip340Schnorr.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { schnorr, secp256k1 } from "@noble/curves/secp256k1.js";
|
|
5
5
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
6
|
+
import { ensureByteArray } from "./validateBytes.js";
|
|
6
7
|
export const BIP340_SCHNORR_SECRET_KEY_LENGTH = 32;
|
|
7
8
|
export const BIP340_SCHNORR_PUBLIC_KEY_LENGTH = 32;
|
|
8
9
|
export const BIP340_SCHNORR_MESSAGE_LENGTH = 32;
|
|
@@ -27,10 +28,12 @@ export const ReallyMeBip340Schnorr = {
|
|
|
27
28
|
deriveKeyPair(secretKey) {
|
|
28
29
|
return {
|
|
29
30
|
publicKey: this.derivePublicKey(secretKey),
|
|
30
|
-
|
|
31
|
+
// Buffer.slice() aliases its input; the returned key must own its bytes.
|
|
32
|
+
secretKey: new Uint8Array(secretKey),
|
|
31
33
|
};
|
|
32
34
|
},
|
|
33
35
|
derivePublicKey(secretKey) {
|
|
36
|
+
ensureByteArray(secretKey);
|
|
34
37
|
if (secretKey.length !== BIP340_SCHNORR_SECRET_KEY_LENGTH) {
|
|
35
38
|
throw new ReallyMeCryptoError("invalid-input");
|
|
36
39
|
}
|
|
@@ -42,6 +45,9 @@ export const ReallyMeBip340Schnorr = {
|
|
|
42
45
|
}
|
|
43
46
|
},
|
|
44
47
|
sign(message32, secretKey, auxRand32) {
|
|
48
|
+
ensureByteArray(message32);
|
|
49
|
+
ensureByteArray(secretKey);
|
|
50
|
+
ensureByteArray(auxRand32);
|
|
45
51
|
if (message32.length !== BIP340_SCHNORR_MESSAGE_LENGTH ||
|
|
46
52
|
secretKey.length !== BIP340_SCHNORR_SECRET_KEY_LENGTH ||
|
|
47
53
|
auxRand32.length !== BIP340_SCHNORR_AUX_RAND_LENGTH) {
|
|
@@ -55,6 +61,9 @@ export const ReallyMeBip340Schnorr = {
|
|
|
55
61
|
}
|
|
56
62
|
},
|
|
57
63
|
verify(signature, message32, publicKey) {
|
|
64
|
+
ensureByteArray(signature);
|
|
65
|
+
ensureByteArray(message32);
|
|
66
|
+
ensureByteArray(publicKey);
|
|
58
67
|
if (signature.length !== BIP340_SCHNORR_SIGNATURE_LENGTH ||
|
|
59
68
|
message32.length !== BIP340_SCHNORR_MESSAGE_LENGTH ||
|
|
60
69
|
publicKey.length !== BIP340_SCHNORR_PUBLIC_KEY_LENGTH) {
|
package/dist/cryptoFacade.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { ReallyMeAead } from "./aead.js";
|
|
5
5
|
import { ReallyMeAesKw } from "./aesKw.js";
|
|
6
6
|
import { ReallyMeArgon2id } from "./argon2id.js";
|
package/dist/digest.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { sha256 as nobleSha256, sha384 as nobleSha384, sha512 as nobleSha512 } from "@noble/hashes/sha2.js";
|
|
5
5
|
import { sha3_224 as nobleSha3_224, sha3_256 as nobleSha3_256, sha3_384 as nobleSha3_384, sha3_512 as nobleSha3_512, } from "@noble/hashes/sha3.js";
|
|
6
|
+
import { ensureByteArray } from "./validateBytes.js";
|
|
6
7
|
/**
|
|
7
8
|
* Small digest surface used by package tests and as the first package API
|
|
8
9
|
* slice while algorithm wrappers are added one at a time. Mirrors the Swift
|
|
@@ -10,24 +11,31 @@ import { sha3_224 as nobleSha3_224, sha3_256 as nobleSha3_256, sha3_384 as noble
|
|
|
10
11
|
*/
|
|
11
12
|
export const ReallyMeDigest = {
|
|
12
13
|
sha256(bytes) {
|
|
14
|
+
ensureByteArray(bytes);
|
|
13
15
|
return nobleSha256(bytes);
|
|
14
16
|
},
|
|
15
17
|
sha384(bytes) {
|
|
18
|
+
ensureByteArray(bytes);
|
|
16
19
|
return nobleSha384(bytes);
|
|
17
20
|
},
|
|
18
21
|
sha512(bytes) {
|
|
22
|
+
ensureByteArray(bytes);
|
|
19
23
|
return nobleSha512(bytes);
|
|
20
24
|
},
|
|
21
25
|
sha3_224(bytes) {
|
|
26
|
+
ensureByteArray(bytes);
|
|
22
27
|
return nobleSha3_224(bytes);
|
|
23
28
|
},
|
|
24
29
|
sha3_256(bytes) {
|
|
30
|
+
ensureByteArray(bytes);
|
|
25
31
|
return nobleSha3_256(bytes);
|
|
26
32
|
},
|
|
27
33
|
sha3_384(bytes) {
|
|
34
|
+
ensureByteArray(bytes);
|
|
28
35
|
return nobleSha3_384(bytes);
|
|
29
36
|
},
|
|
30
37
|
sha3_512(bytes) {
|
|
38
|
+
ensureByteArray(bytes);
|
|
31
39
|
return nobleSha3_512(bytes);
|
|
32
40
|
},
|
|
33
41
|
};
|
package/dist/ed25519.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { ed25519 } from "@noble/curves/ed25519.js";
|
|
5
5
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
6
|
+
import { ensureByteArray } from "./validateBytes.js";
|
|
6
7
|
/**
|
|
7
8
|
* Ed25519 signatures backed by @noble/curves — the same pinned implementation
|
|
8
9
|
* the TypeScript conformance lane proves vectors against.
|
|
@@ -33,11 +34,13 @@ export const ReallyMeEd25519 = {
|
|
|
33
34
|
deriveKeyPair(secretKey) {
|
|
34
35
|
return {
|
|
35
36
|
publicKey: this.derivePublicKey(secretKey),
|
|
36
|
-
|
|
37
|
+
// Buffer.slice() aliases its input; the returned key must own its bytes.
|
|
38
|
+
secretKey: new Uint8Array(secretKey),
|
|
37
39
|
};
|
|
38
40
|
},
|
|
39
41
|
/** Derives the 32-byte Ed25519 public key from a 32-byte seed. */
|
|
40
42
|
derivePublicKey(secretKey) {
|
|
43
|
+
ensureByteArray(secretKey);
|
|
41
44
|
if (secretKey.length !== ED25519_SECRET_KEY_LENGTH) {
|
|
42
45
|
throw new ReallyMeCryptoError("invalid-input");
|
|
43
46
|
}
|
|
@@ -50,6 +53,8 @@ export const ReallyMeEd25519 = {
|
|
|
50
53
|
},
|
|
51
54
|
/** Signs the full message using plain deterministic Ed25519. */
|
|
52
55
|
sign(message, secretKey) {
|
|
56
|
+
ensureByteArray(message);
|
|
57
|
+
ensureByteArray(secretKey);
|
|
53
58
|
if (secretKey.length !== ED25519_SECRET_KEY_LENGTH) {
|
|
54
59
|
throw new ReallyMeCryptoError("invalid-input");
|
|
55
60
|
}
|
|
@@ -66,6 +71,9 @@ export const ReallyMeEd25519 = {
|
|
|
66
71
|
* Throws on malformed input shape, undecodable keys, or invalid signatures.
|
|
67
72
|
*/
|
|
68
73
|
verify(signature, message, publicKey) {
|
|
74
|
+
ensureByteArray(signature);
|
|
75
|
+
ensureByteArray(message);
|
|
76
|
+
ensureByteArray(publicKey);
|
|
69
77
|
if (signature.length !== ED25519_SIGNATURE_LENGTH ||
|
|
70
78
|
publicKey.length !== ED25519_PUBLIC_KEY_LENGTH) {
|
|
71
79
|
throw new ReallyMeCryptoError("invalid-input");
|
package/dist/encodeEcdsaDer.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
5
5
|
const DER_SEQUENCE_TAG = 0x30;
|
|
6
6
|
const DER_INTEGER_TAG = 0x02;
|
package/dist/errors.js
CHANGED
package/dist/hkdf.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { hkdf } from "@noble/hashes/hkdf.js";
|
|
5
5
|
import { sha256, sha384 } from "@noble/hashes/sha2.js";
|
|
6
6
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
7
|
+
import { ensureByteArray } from "./validateBytes.js";
|
|
7
8
|
export const HKDF_MIN_INPUT_KEY_MATERIAL_LENGTH = 1;
|
|
8
9
|
export const HKDF_MAX_INPUT_LENGTH = 4096;
|
|
9
10
|
export const HKDF_MIN_OUTPUT_LENGTH = 1;
|
|
@@ -19,6 +20,9 @@ export const ReallyMeHkdf = {
|
|
|
19
20
|
},
|
|
20
21
|
};
|
|
21
22
|
function validate(inputKeyMaterial, salt, info, outputLength) {
|
|
23
|
+
ensureByteArray(inputKeyMaterial);
|
|
24
|
+
ensureByteArray(salt);
|
|
25
|
+
ensureByteArray(info);
|
|
22
26
|
if (inputKeyMaterial.length < HKDF_MIN_INPUT_KEY_MATERIAL_LENGTH ||
|
|
23
27
|
inputKeyMaterial.length > HKDF_MAX_INPUT_LENGTH ||
|
|
24
28
|
salt.length > HKDF_MAX_INPUT_LENGTH ||
|
package/dist/hmac.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { hmac } from "@noble/hashes/hmac.js";
|
|
5
5
|
import { sha256, sha384, sha512 } from "@noble/hashes/sha2.js";
|
|
6
6
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
7
|
+
import { ensureByteArray } from "./validateBytes.js";
|
|
7
8
|
export const HMAC_MAX_KEY_LENGTH = 4096;
|
|
8
9
|
export const HMAC_SHA256_TAG_LENGTH = 32;
|
|
9
10
|
export const HMAC_SHA384_TAG_LENGTH = 48;
|
|
@@ -11,29 +12,35 @@ export const HMAC_SHA512_TAG_LENGTH = 64;
|
|
|
11
12
|
export const ReallyMeHmac = {
|
|
12
13
|
authenticateSha256(key, message) {
|
|
13
14
|
validateKey(key);
|
|
15
|
+
ensureByteArray(message);
|
|
14
16
|
return hmac(sha256, key, message);
|
|
15
17
|
},
|
|
16
18
|
authenticateSha384(key, message) {
|
|
17
19
|
validateKey(key);
|
|
20
|
+
ensureByteArray(message);
|
|
18
21
|
return hmac(sha384, key, message);
|
|
19
22
|
},
|
|
20
23
|
authenticateSha512(key, message) {
|
|
21
24
|
validateKey(key);
|
|
25
|
+
ensureByteArray(message);
|
|
22
26
|
return hmac(sha512, key, message);
|
|
23
27
|
},
|
|
24
28
|
verifySha256(tag, key, message) {
|
|
29
|
+
ensureByteArray(tag);
|
|
25
30
|
if (tag.length !== HMAC_SHA256_TAG_LENGTH) {
|
|
26
31
|
throw new ReallyMeCryptoError("invalid-input");
|
|
27
32
|
}
|
|
28
33
|
return verifyAndClearExpectedTag(tag, ReallyMeHmac.authenticateSha256(key, message));
|
|
29
34
|
},
|
|
30
35
|
verifySha384(tag, key, message) {
|
|
36
|
+
ensureByteArray(tag);
|
|
31
37
|
if (tag.length !== HMAC_SHA384_TAG_LENGTH) {
|
|
32
38
|
throw new ReallyMeCryptoError("invalid-input");
|
|
33
39
|
}
|
|
34
40
|
return verifyAndClearExpectedTag(tag, ReallyMeHmac.authenticateSha384(key, message));
|
|
35
41
|
},
|
|
36
42
|
verifySha512(tag, key, message) {
|
|
43
|
+
ensureByteArray(tag);
|
|
37
44
|
if (tag.length !== HMAC_SHA512_TAG_LENGTH) {
|
|
38
45
|
throw new ReallyMeCryptoError("invalid-input");
|
|
39
46
|
}
|
|
@@ -41,6 +48,7 @@ export const ReallyMeHmac = {
|
|
|
41
48
|
},
|
|
42
49
|
};
|
|
43
50
|
function validateKey(key) {
|
|
51
|
+
ensureByteArray(key);
|
|
44
52
|
if (key.length === 0 || key.length > HMAC_MAX_KEY_LENGTH) {
|
|
45
53
|
throw new ReallyMeCryptoError("invalid-input");
|
|
46
54
|
}
|
|
@@ -50,9 +58,10 @@ function constantTimeEquals(left, right) {
|
|
|
50
58
|
return false;
|
|
51
59
|
}
|
|
52
60
|
let difference = 0;
|
|
53
|
-
for (
|
|
61
|
+
for (let index = 0; index < left.length; index += 1) {
|
|
62
|
+
const leftByte = left[index];
|
|
54
63
|
const rightByte = right[index];
|
|
55
|
-
if (rightByte === undefined) {
|
|
64
|
+
if (leftByte === undefined || rightByte === undefined) {
|
|
56
65
|
return false;
|
|
57
66
|
}
|
|
58
67
|
difference |= leftByte ^ rightByte;
|
package/dist/hpke.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
5
5
|
import { ensureByteArrayAtMost, ensureBytes, ensureIndependentByteArray, MAX_CRYPTO_INPUT_LENGTH, readIndependentByteArrayProperty, } from "./validateBytes.js";
|
|
6
6
|
import { requireReallyMeWasmProvider } from "./wasmProvider.js";
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
export { ReallyMeCryptoError } from "./errors.js";
|
|
5
5
|
export { REALLYME_AEAD_ALGORITHMS, REALLYME_HASH_ALGORITHMS, REALLYME_HPKE_SUITES, REALLYME_KDF_ALGORITHMS, REALLYME_KEM_ALGORITHMS, REALLYME_KEY_AGREEMENT_ALGORITHMS, REALLYME_KEY_WRAP_ALGORITHMS, REALLYME_MAC_ALGORITHMS, REALLYME_SIGNATURE_ALGORITHMS, } from "./algorithms.js";
|
|
6
6
|
export { AEAD_KEY_LENGTH, AEAD_NONCE_LENGTH, AEAD_TAG_LENGTH, AES_128_GCM_KEY_LENGTH, AES_192_GCM_KEY_LENGTH, AES_256_GCM_KEY_LENGTH, CHACHA20_POLY1305_KEY_LENGTH, ReallyMeAead, XCHACHA20_POLY1305_NONCE_LENGTH, } from "./aead.js";
|
package/dist/jwaConcatKdf.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { sha256 } from "@noble/hashes/sha2.js";
|
|
5
5
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
6
|
+
import { ensureByteArray } from "./validateBytes.js";
|
|
6
7
|
import { bestEffortClear } from "./memory.js";
|
|
7
8
|
export const JWA_CONCAT_KDF_SHA256_DIGEST_LENGTH = 32;
|
|
8
9
|
export const JWA_CONCAT_KDF_MAX_SHARED_SECRET_LENGTH = 4096;
|
|
@@ -32,6 +33,10 @@ export const ReallyMeJwaConcatKdf = {
|
|
|
32
33
|
},
|
|
33
34
|
};
|
|
34
35
|
function validate(sharedSecret, algorithmId, partyUInfo, partyVInfo, outputLength) {
|
|
36
|
+
ensureByteArray(sharedSecret);
|
|
37
|
+
ensureByteArray(algorithmId);
|
|
38
|
+
ensureByteArray(partyUInfo);
|
|
39
|
+
ensureByteArray(partyVInfo);
|
|
35
40
|
if (sharedSecret.length === 0 ||
|
|
36
41
|
sharedSecret.length > JWA_CONCAT_KDF_MAX_SHARED_SECRET_LENGTH ||
|
|
37
42
|
algorithmId.length === 0 ||
|
package/dist/jwk.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { p256 } from "@noble/curves/nist.js";
|
|
5
5
|
import { secp256k1 } from "@noble/curves/secp256k1.js";
|
|
6
6
|
import { base64urlDecode as codecBase64urlDecodeValue, base64urlEncode as codecBase64urlEncodeValue, canonicalizeJson as codecCanonicalizeJson, ReallyMeCodecError, } from "@reallyme/codec";
|
package/dist/kmac.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
5
5
|
import { ensureByteArray, ensureIndependentByteArray, } from "./validateBytes.js";
|
|
6
6
|
import { requireReallyMeWasmProvider } from "./wasmProvider.js";
|
package/dist/memory.js
CHANGED
package/dist/mlDsa.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
5
5
|
import { ensureByteArrayAtMost, ensureBytes, ensureIndependentByteArray, MAX_CRYPTO_INPUT_LENGTH, readIndependentByteArrayProperty, } from "./validateBytes.js";
|
|
6
6
|
import { requireReallyMeWasmProvider } from "./wasmProvider.js";
|
package/dist/mlKem.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
5
5
|
import { ensureBytes, readIndependentByteArrayProperty, readIndependentProviderBytes, } from "./validateBytes.js";
|
|
6
6
|
import { requireReallyMeWasmProvider } from "./wasmProvider.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
5
5
|
import { ensureByteArray, ensureIndependentByteArray, } from "./validateBytes.js";
|
|
6
6
|
import { requireReallyMeWasmProvider } from "./wasmProvider.js";
|
package/dist/p256Ecdh.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { p256 } from "@noble/curves/nist.js";
|
|
5
5
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
6
|
+
import { ensureByteArray } from "./validateBytes.js";
|
|
6
7
|
import { bestEffortClear } from "./memory.js";
|
|
7
8
|
/**
|
|
8
9
|
* P-256 ECDH backed by @noble/curves.
|
|
@@ -25,10 +26,12 @@ export const ReallyMeP256Ecdh = {
|
|
|
25
26
|
deriveKeyPair(secretKey) {
|
|
26
27
|
return {
|
|
27
28
|
publicKey: this.derivePublicKey(secretKey),
|
|
28
|
-
|
|
29
|
+
// Buffer.slice() aliases its input; the returned key must own its bytes.
|
|
30
|
+
secretKey: new Uint8Array(secretKey),
|
|
29
31
|
};
|
|
30
32
|
},
|
|
31
33
|
derivePublicKey(secretKey) {
|
|
34
|
+
ensureByteArray(secretKey);
|
|
32
35
|
if (secretKey.length !== P256_ECDH_SECRET_KEY_LENGTH) {
|
|
33
36
|
throw new ReallyMeCryptoError("invalid-input");
|
|
34
37
|
}
|
|
@@ -40,6 +43,8 @@ export const ReallyMeP256Ecdh = {
|
|
|
40
43
|
}
|
|
41
44
|
},
|
|
42
45
|
deriveSharedSecret(publicKey, secretKey) {
|
|
46
|
+
ensureByteArray(publicKey);
|
|
47
|
+
ensureByteArray(secretKey);
|
|
43
48
|
if (publicKey.length !== P256_ECDH_COMPRESSED_PUBLIC_KEY_LENGTH ||
|
|
44
49
|
secretKey.length !== P256_ECDH_SECRET_KEY_LENGTH) {
|
|
45
50
|
throw new ReallyMeCryptoError("invalid-input");
|
package/dist/p256Ecdsa.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { p256 } from "@noble/curves/nist.js";
|
|
5
5
|
import { sha256 } from "@noble/hashes/sha2.js";
|
|
6
6
|
import { decodeEcdsaDerSignature, encodeEcdsaDerSignature, } from "./encodeEcdsaDer.js";
|
|
7
7
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
8
|
+
import { ensureByteArray } from "./validateBytes.js";
|
|
8
9
|
export const P256_ECDSA_SECRET_KEY_LENGTH = 32;
|
|
9
10
|
export const P256_ECDSA_COMPRESSED_PUBLIC_KEY_LENGTH = 33;
|
|
10
11
|
export const P256_ECDSA_COMPACT_SIGNATURE_LENGTH = 64;
|
|
@@ -28,10 +29,12 @@ export const ReallyMeP256Ecdsa = {
|
|
|
28
29
|
deriveKeyPair(secretKey) {
|
|
29
30
|
return {
|
|
30
31
|
publicKey: this.derivePublicKey(secretKey),
|
|
31
|
-
|
|
32
|
+
// Buffer.slice() aliases its input; the returned key must own its bytes.
|
|
33
|
+
secretKey: new Uint8Array(secretKey),
|
|
32
34
|
};
|
|
33
35
|
},
|
|
34
36
|
derivePublicKey(secretKey) {
|
|
37
|
+
ensureByteArray(secretKey);
|
|
35
38
|
if (secretKey.length !== P256_ECDSA_SECRET_KEY_LENGTH) {
|
|
36
39
|
throw new ReallyMeCryptoError("invalid-input");
|
|
37
40
|
}
|
|
@@ -43,6 +46,8 @@ export const ReallyMeP256Ecdsa = {
|
|
|
43
46
|
}
|
|
44
47
|
},
|
|
45
48
|
sign(message, secretKey) {
|
|
49
|
+
ensureByteArray(message);
|
|
50
|
+
ensureByteArray(secretKey);
|
|
46
51
|
if (secretKey.length !== P256_ECDSA_SECRET_KEY_LENGTH) {
|
|
47
52
|
throw new ReallyMeCryptoError("invalid-input");
|
|
48
53
|
}
|
|
@@ -58,6 +63,9 @@ export const ReallyMeP256Ecdsa = {
|
|
|
58
63
|
}
|
|
59
64
|
},
|
|
60
65
|
verify(signature, message, publicKey) {
|
|
66
|
+
ensureByteArray(signature);
|
|
67
|
+
ensureByteArray(message);
|
|
68
|
+
ensureByteArray(publicKey);
|
|
61
69
|
if (publicKey.length !== P256_ECDSA_COMPRESSED_PUBLIC_KEY_LENGTH) {
|
|
62
70
|
throw new ReallyMeCryptoError("invalid-input");
|
|
63
71
|
}
|
package/dist/p384Ecdh.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { p384 } from "@noble/curves/nist.js";
|
|
5
5
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
6
|
+
import { ensureByteArray } from "./validateBytes.js";
|
|
6
7
|
import { bestEffortClear } from "./memory.js";
|
|
7
8
|
/**
|
|
8
9
|
* P-384 ECDH backed by @noble/curves.
|
|
@@ -25,10 +26,12 @@ export const ReallyMeP384Ecdh = {
|
|
|
25
26
|
deriveKeyPair(secretKey) {
|
|
26
27
|
return {
|
|
27
28
|
publicKey: this.derivePublicKey(secretKey),
|
|
28
|
-
|
|
29
|
+
// Buffer.slice() aliases its input; the returned key must own its bytes.
|
|
30
|
+
secretKey: new Uint8Array(secretKey),
|
|
29
31
|
};
|
|
30
32
|
},
|
|
31
33
|
derivePublicKey(secretKey) {
|
|
34
|
+
ensureByteArray(secretKey);
|
|
32
35
|
if (secretKey.length !== P384_ECDH_SECRET_KEY_LENGTH) {
|
|
33
36
|
throw new ReallyMeCryptoError("invalid-input");
|
|
34
37
|
}
|
|
@@ -40,6 +43,8 @@ export const ReallyMeP384Ecdh = {
|
|
|
40
43
|
}
|
|
41
44
|
},
|
|
42
45
|
deriveSharedSecret(publicKey, secretKey) {
|
|
46
|
+
ensureByteArray(publicKey);
|
|
47
|
+
ensureByteArray(secretKey);
|
|
43
48
|
if (publicKey.length !== P384_ECDH_COMPRESSED_PUBLIC_KEY_LENGTH ||
|
|
44
49
|
secretKey.length !== P384_ECDH_SECRET_KEY_LENGTH) {
|
|
45
50
|
throw new ReallyMeCryptoError("invalid-input");
|
package/dist/p384Ecdsa.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { p384 } from "@noble/curves/nist.js";
|
|
5
5
|
import { sha384 } from "@noble/hashes/sha2.js";
|
|
6
6
|
import { decodeEcdsaDerSignature, encodeEcdsaDerSignature, } from "./encodeEcdsaDer.js";
|
|
7
7
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
8
|
+
import { ensureByteArray } from "./validateBytes.js";
|
|
8
9
|
export const P384_ECDSA_SECRET_KEY_LENGTH = 48;
|
|
9
10
|
export const P384_ECDSA_COMPRESSED_PUBLIC_KEY_LENGTH = 49;
|
|
10
11
|
export const P384_ECDSA_COMPACT_SIGNATURE_LENGTH = 96;
|
|
@@ -26,10 +27,12 @@ export const ReallyMeP384Ecdsa = {
|
|
|
26
27
|
deriveKeyPair(secretKey) {
|
|
27
28
|
return {
|
|
28
29
|
publicKey: this.derivePublicKey(secretKey),
|
|
29
|
-
|
|
30
|
+
// Buffer.slice() aliases its input; the returned key must own its bytes.
|
|
31
|
+
secretKey: new Uint8Array(secretKey),
|
|
30
32
|
};
|
|
31
33
|
},
|
|
32
34
|
derivePublicKey(secretKey) {
|
|
35
|
+
ensureByteArray(secretKey);
|
|
33
36
|
if (secretKey.length !== P384_ECDSA_SECRET_KEY_LENGTH) {
|
|
34
37
|
throw new ReallyMeCryptoError("invalid-input");
|
|
35
38
|
}
|
|
@@ -41,6 +44,8 @@ export const ReallyMeP384Ecdsa = {
|
|
|
41
44
|
}
|
|
42
45
|
},
|
|
43
46
|
sign(message, secretKey) {
|
|
47
|
+
ensureByteArray(message);
|
|
48
|
+
ensureByteArray(secretKey);
|
|
44
49
|
if (secretKey.length !== P384_ECDSA_SECRET_KEY_LENGTH) {
|
|
45
50
|
throw new ReallyMeCryptoError("invalid-input");
|
|
46
51
|
}
|
|
@@ -56,6 +61,9 @@ export const ReallyMeP384Ecdsa = {
|
|
|
56
61
|
}
|
|
57
62
|
},
|
|
58
63
|
verify(signature, message, publicKey) {
|
|
64
|
+
ensureByteArray(signature);
|
|
65
|
+
ensureByteArray(message);
|
|
66
|
+
ensureByteArray(publicKey);
|
|
59
67
|
if (publicKey.length !== P384_ECDSA_COMPRESSED_PUBLIC_KEY_LENGTH) {
|
|
60
68
|
throw new ReallyMeCryptoError("invalid-input");
|
|
61
69
|
}
|
package/dist/p521Ecdh.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { p521 } from "@noble/curves/nist.js";
|
|
5
5
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
6
|
+
import { ensureByteArray } from "./validateBytes.js";
|
|
6
7
|
import { bestEffortClear } from "./memory.js";
|
|
7
8
|
/**
|
|
8
9
|
* P-521 ECDH backed by @noble/curves.
|
|
@@ -25,10 +26,12 @@ export const ReallyMeP521Ecdh = {
|
|
|
25
26
|
deriveKeyPair(secretKey) {
|
|
26
27
|
return {
|
|
27
28
|
publicKey: this.derivePublicKey(secretKey),
|
|
28
|
-
|
|
29
|
+
// Buffer.slice() aliases its input; the returned key must own its bytes.
|
|
30
|
+
secretKey: new Uint8Array(secretKey),
|
|
29
31
|
};
|
|
30
32
|
},
|
|
31
33
|
derivePublicKey(secretKey) {
|
|
34
|
+
ensureByteArray(secretKey);
|
|
32
35
|
if (secretKey.length !== P521_ECDH_SECRET_KEY_LENGTH) {
|
|
33
36
|
throw new ReallyMeCryptoError("invalid-input");
|
|
34
37
|
}
|
|
@@ -40,6 +43,8 @@ export const ReallyMeP521Ecdh = {
|
|
|
40
43
|
}
|
|
41
44
|
},
|
|
42
45
|
deriveSharedSecret(publicKey, secretKey) {
|
|
46
|
+
ensureByteArray(publicKey);
|
|
47
|
+
ensureByteArray(secretKey);
|
|
43
48
|
if (publicKey.length !== P521_ECDH_COMPRESSED_PUBLIC_KEY_LENGTH ||
|
|
44
49
|
secretKey.length !== P521_ECDH_SECRET_KEY_LENGTH) {
|
|
45
50
|
throw new ReallyMeCryptoError("invalid-input");
|
package/dist/p521Ecdsa.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { p521 } from "@noble/curves/nist.js";
|
|
5
5
|
import { sha512 } from "@noble/hashes/sha2.js";
|
|
6
6
|
import { decodeEcdsaDerSignature, encodeEcdsaDerSignature, } from "./encodeEcdsaDer.js";
|
|
7
7
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
8
|
+
import { ensureByteArray } from "./validateBytes.js";
|
|
8
9
|
export const P521_ECDSA_SECRET_KEY_LENGTH = 66;
|
|
9
10
|
export const P521_ECDSA_COMPRESSED_PUBLIC_KEY_LENGTH = 67;
|
|
10
11
|
export const P521_ECDSA_COMPACT_SIGNATURE_LENGTH = 132;
|
|
@@ -26,10 +27,12 @@ export const ReallyMeP521Ecdsa = {
|
|
|
26
27
|
deriveKeyPair(secretKey) {
|
|
27
28
|
return {
|
|
28
29
|
publicKey: this.derivePublicKey(secretKey),
|
|
29
|
-
|
|
30
|
+
// Buffer.slice() aliases its input; the returned key must own its bytes.
|
|
31
|
+
secretKey: new Uint8Array(secretKey),
|
|
30
32
|
};
|
|
31
33
|
},
|
|
32
34
|
derivePublicKey(secretKey) {
|
|
35
|
+
ensureByteArray(secretKey);
|
|
33
36
|
if (secretKey.length !== P521_ECDSA_SECRET_KEY_LENGTH) {
|
|
34
37
|
throw new ReallyMeCryptoError("invalid-input");
|
|
35
38
|
}
|
|
@@ -41,6 +44,8 @@ export const ReallyMeP521Ecdsa = {
|
|
|
41
44
|
}
|
|
42
45
|
},
|
|
43
46
|
sign(message, secretKey) {
|
|
47
|
+
ensureByteArray(message);
|
|
48
|
+
ensureByteArray(secretKey);
|
|
44
49
|
if (secretKey.length !== P521_ECDSA_SECRET_KEY_LENGTH) {
|
|
45
50
|
throw new ReallyMeCryptoError("invalid-input");
|
|
46
51
|
}
|
|
@@ -56,6 +61,9 @@ export const ReallyMeP521Ecdsa = {
|
|
|
56
61
|
}
|
|
57
62
|
},
|
|
58
63
|
verify(signature, message, publicKey) {
|
|
64
|
+
ensureByteArray(signature);
|
|
65
|
+
ensureByteArray(message);
|
|
66
|
+
ensureByteArray(publicKey);
|
|
59
67
|
if (publicKey.length !== P521_ECDSA_COMPRESSED_PUBLIC_KEY_LENGTH) {
|
|
60
68
|
throw new ReallyMeCryptoError("invalid-input");
|
|
61
69
|
}
|
package/dist/pbkdf2.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { pbkdf2 } from "@noble/hashes/pbkdf2.js";
|
|
5
5
|
import { sha256, sha512 } from "@noble/hashes/sha2.js";
|
|
6
6
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
7
|
+
import { ensureByteArray } from "./validateBytes.js";
|
|
7
8
|
export const PBKDF2_MIN_INPUT_LENGTH = 1;
|
|
8
9
|
export const PBKDF2_MAX_INPUT_LENGTH = 4096;
|
|
9
10
|
// Public derivation routes enforce a modern baseline. Historical hashes with a
|
|
@@ -42,6 +43,8 @@ export const ReallyMePbkdf2 = {
|
|
|
42
43
|
},
|
|
43
44
|
};
|
|
44
45
|
function validate(password, salt, iterations, outputLength) {
|
|
46
|
+
ensureByteArray(password);
|
|
47
|
+
ensureByteArray(salt);
|
|
45
48
|
if (password.length < PBKDF2_MIN_INPUT_LENGTH ||
|
|
46
49
|
password.length > PBKDF2_MAX_INPUT_LENGTH ||
|
|
47
50
|
salt.length < PBKDF2_MIN_INPUT_LENGTH ||
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { enumDesc, fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
|
|
5
5
|
/**
|
|
6
6
|
* Describes the file reallyme/crypto/v1/crypto.proto.
|
package/dist/proto.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { create, fromBinary, toBinary } from "@bufbuild/protobuf";
|
|
5
5
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
6
6
|
import { MAX_JWKS_KEYS, ReallyMeJwk } from "./jwk.js";
|
package/dist/providerCatalog.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
/** Providers compiled into the TypeScript package. */
|
|
5
5
|
export const REALLYME_CRYPTO_PROVIDERS = [
|
|
6
6
|
"@noble/curves",
|
package/dist/rsa.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
5
5
|
import { ensureByteArray, ensureByteArrayAtMost, MAX_CRYPTO_INPUT_LENGTH, } from "./validateBytes.js";
|
|
6
6
|
import { requireReallyMeWasmProvider } from "./wasmProvider.js";
|
package/dist/secp256k1.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { secp256k1 } from "@noble/curves/secp256k1.js";
|
|
5
5
|
import { sha256 } from "@noble/hashes/sha2.js";
|
|
6
6
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
7
|
+
import { ensureByteArray } from "./validateBytes.js";
|
|
7
8
|
/**
|
|
8
9
|
* secp256k1 ECDSA backed by @noble/curves — the same pinned implementation
|
|
9
10
|
* the TypeScript conformance lane proves vectors against.
|
|
@@ -36,11 +37,13 @@ export const ReallyMeSecp256k1 = {
|
|
|
36
37
|
deriveKeyPair(secretKey) {
|
|
37
38
|
return {
|
|
38
39
|
publicKey: this.derivePublicKey(secretKey),
|
|
39
|
-
|
|
40
|
+
// Buffer.slice() aliases its input; the returned key must own its bytes.
|
|
41
|
+
secretKey: new Uint8Array(secretKey),
|
|
40
42
|
};
|
|
41
43
|
},
|
|
42
44
|
/** Derives the 33-byte compressed SEC1 public key for a 32-byte secret. */
|
|
43
45
|
derivePublicKey(secretKey) {
|
|
46
|
+
ensureByteArray(secretKey);
|
|
44
47
|
if (secretKey.length !== SECP256K1_SECRET_KEY_LENGTH) {
|
|
45
48
|
throw new ReallyMeCryptoError("invalid-input");
|
|
46
49
|
}
|
|
@@ -56,6 +59,8 @@ export const ReallyMeSecp256k1 = {
|
|
|
56
59
|
* SHA-256(message), returning the 64-byte compact low-S signature.
|
|
57
60
|
*/
|
|
58
61
|
sign(message, secretKey) {
|
|
62
|
+
ensureByteArray(message);
|
|
63
|
+
ensureByteArray(secretKey);
|
|
59
64
|
if (secretKey.length !== SECP256K1_SECRET_KEY_LENGTH) {
|
|
60
65
|
throw new ReallyMeCryptoError("invalid-input");
|
|
61
66
|
}
|
|
@@ -80,6 +85,9 @@ export const ReallyMeSecp256k1 = {
|
|
|
80
85
|
* high-S twin (BIP 0062), which every workspace lane rejects.
|
|
81
86
|
*/
|
|
82
87
|
verify(signature, message, publicKey) {
|
|
88
|
+
ensureByteArray(signature);
|
|
89
|
+
ensureByteArray(message);
|
|
90
|
+
ensureByteArray(publicKey);
|
|
83
91
|
if (signature.length !== SECP256K1_SIGNATURE_LENGTH ||
|
|
84
92
|
publicKey.length !== SECP256K1_COMPRESSED_PUBLIC_KEY_LENGTH) {
|
|
85
93
|
throw new ReallyMeCryptoError("invalid-input");
|
package/dist/slhDsa.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
5
5
|
import { ensureByteArrayAtMost, ensureBytes, ensureIndependentByteArray, MAX_CRYPTO_INPUT_LENGTH, readIndependentByteArrayProperty, } from "./validateBytes.js";
|
|
6
6
|
import { requireReallyMeWasmProvider } from "./wasmProvider.js";
|
package/dist/validateBytes.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const MAX_CRYPTO_INPUT_LENGTH = 1048576;
|
|
2
|
-
export declare
|
|
2
|
+
export declare function ensureByteArray(value: unknown): asserts value is Uint8Array;
|
|
3
3
|
export declare const ensureByteArrayAtMost: (value: Uint8Array, maximumLength: number) => void;
|
|
4
4
|
export declare const ensureBytes: (value: Uint8Array, expectedLength: number) => void;
|
|
5
5
|
export declare const byteArraysOverlap: (left: Uint8Array, right: Uint8Array) => boolean;
|
package/dist/validateBytes.js
CHANGED
|
@@ -1,15 +1,31 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
5
5
|
// Match the structured operation boundary so direct primitive facades cannot
|
|
6
6
|
// ask a provider to copy or allocate an attacker-controlled unbounded buffer.
|
|
7
7
|
export const MAX_CRYPTO_INPUT_LENGTH = 1_048_576;
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
// The intrinsic getter reads the typed-array element kind from internal slots.
|
|
9
|
+
// instanceof rejects legitimate arrays from other realms, while an object's
|
|
10
|
+
// constructor name or own toStringTag can be spoofed.
|
|
11
|
+
const typedArrayTagGetter = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(Uint8Array.prototype), Symbol.toStringTag)?.get;
|
|
12
|
+
export function ensureByteArray(value) {
|
|
13
|
+
if (!ArrayBuffer.isView(value) || typedArrayTagGetter === undefined) {
|
|
10
14
|
throw new ReallyMeCryptoError("invalid-input");
|
|
11
15
|
}
|
|
12
|
-
|
|
16
|
+
try {
|
|
17
|
+
const elementKind = Reflect.apply(typedArrayTagGetter, value, []);
|
|
18
|
+
if (elementKind !== "Uint8Array") {
|
|
19
|
+
throw new ReallyMeCryptoError("invalid-input");
|
|
20
|
+
}
|
|
21
|
+
// Detached views report zero length; validate the backing store before a
|
|
22
|
+
// provider can confuse them with an intentionally empty message.
|
|
23
|
+
Uint8Array.prototype.values.call(value);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
throw new ReallyMeCryptoError("invalid-input");
|
|
27
|
+
}
|
|
28
|
+
}
|
|
13
29
|
export const ensureByteArrayAtMost = (value, maximumLength) => {
|
|
14
30
|
ensureByteArray(value);
|
|
15
31
|
if (value.length > maximumLength) {
|
package/dist/wasm/LICENSE
CHANGED
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
ReallyMe Crypto is licensed, at your option, under either the MIT License or
|
|
2
|
+
the Apache License, Version 2.0. The full text of both licenses follows.
|
|
3
|
+
Third-party components retain their own licenses and notices.
|
|
4
|
+
|
|
5
|
+
MIT License
|
|
6
|
+
|
|
7
|
+
Copyright © 2026 ReallyMe LLC.
|
|
8
|
+
|
|
9
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
10
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
11
|
+
in the Software without restriction, including without limitation the rights
|
|
12
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
13
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
14
|
+
furnished to do so, subject to the following conditions:
|
|
15
|
+
|
|
16
|
+
The above copyright notice and this permission notice shall be included in all
|
|
17
|
+
copies or substantial portions of the Software.
|
|
18
|
+
|
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
20
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
21
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
22
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
23
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
24
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
25
|
+
SOFTWARE.
|
|
26
|
+
|
|
1
27
|
Apache License
|
|
2
28
|
Version 2.0, January 2004
|
|
3
29
|
http://www.apache.org/licenses/
|
|
Binary file
|
package/dist/wasmModuleTypes.js
CHANGED
package/dist/wasmProvider.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
5
5
|
let installedProvider;
|
|
6
6
|
const requireObject = (module) => {
|
package/dist/x25519.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { x25519 } from "@noble/curves/ed25519.js";
|
|
5
5
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
6
|
+
import { ensureByteArray } from "./validateBytes.js";
|
|
6
7
|
/**
|
|
7
8
|
* X25519 key agreement backed by @noble/curves — the same pinned
|
|
8
9
|
* implementation the TypeScript conformance lane proves vectors against.
|
|
@@ -28,11 +29,13 @@ export const ReallyMeX25519 = {
|
|
|
28
29
|
deriveKeyPair(secretKey) {
|
|
29
30
|
return {
|
|
30
31
|
publicKey: this.derivePublicKey(secretKey),
|
|
31
|
-
|
|
32
|
+
// Buffer.slice() aliases its input; the returned key must own its bytes.
|
|
33
|
+
secretKey: new Uint8Array(secretKey),
|
|
32
34
|
};
|
|
33
35
|
},
|
|
34
36
|
/** Derives the 32-byte X25519 public key from a 32-byte secret. */
|
|
35
37
|
derivePublicKey(secretKey) {
|
|
38
|
+
ensureByteArray(secretKey);
|
|
36
39
|
if (secretKey.length !== X25519_SECRET_KEY_LENGTH) {
|
|
37
40
|
throw new ReallyMeCryptoError("invalid-input");
|
|
38
41
|
}
|
|
@@ -45,6 +48,8 @@ export const ReallyMeX25519 = {
|
|
|
45
48
|
},
|
|
46
49
|
/** Derives the raw 32-byte X25519 shared secret. */
|
|
47
50
|
deriveSharedSecret(publicKey, secretKey) {
|
|
51
|
+
ensureByteArray(publicKey);
|
|
52
|
+
ensureByteArray(secretKey);
|
|
48
53
|
if (publicKey.length !== X25519_PUBLIC_KEY_LENGTH ||
|
|
49
54
|
secretKey.length !== X25519_SECRET_KEY_LENGTH) {
|
|
50
55
|
throw new ReallyMeCryptoError("invalid-input");
|
package/dist/xWing.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
4
4
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
5
5
|
import { ensureBytes, readIndependentByteArrayProperty, readIndependentProviderBytes, } from "./validateBytes.js";
|
|
6
6
|
import { requireReallyMeWasmProvider } from "./wasmProvider.js";
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reallyme/crypto",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.7",
|
|
4
4
|
"description": "ReallyMe crypto SDK for TypeScript/JavaScript with an explicit, pinned provider set.",
|
|
5
|
-
"license": "Apache-2.0",
|
|
5
|
+
"license": "MIT OR Apache-2.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/reallyme/crypto.git",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"@bufbuild/protobuf": "2.14.1",
|
|
56
56
|
"@noble/curves": "2.4.0",
|
|
57
57
|
"@noble/hashes": "2.4.0",
|
|
58
|
-
"@reallyme/codec": "0.2.
|
|
58
|
+
"@reallyme/codec": "0.2.3"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"typescript": "7.0.2"
|