@talismn/crypto 0.0.0-pr2183-20250930074110 → 0.0.0-pr2275-20251210101511

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.
@@ -1,4 +1,4 @@
1
- import { getPublicKey } from "micro-sr25519";
1
+ import { getPublicKey } from "@scure/sr25519";
2
2
  import type { Keypair } from "../types";
3
3
  export declare const deriveSr25519: (seed: Uint8Array, derivationPath: string) => Keypair;
4
4
  export declare const getPublicKeySr25519: typeof getPublicKey;
@@ -0,0 +1 @@
1
+ export declare const encryptKemAead: (publicKey: Uint8Array, plaintext: Uint8Array) => Promise<Uint8Array<ArrayBufferLike>>;
@@ -0,0 +1 @@
1
+ export * from "./encryptKemAead";
@@ -5,3 +5,4 @@ export * from "./address";
5
5
  export * from "./utils";
6
6
  export * from "./platform";
7
7
  export * from "./hashing";
8
+ export * from "./encryption";
@@ -15,7 +15,10 @@ var scaleTs = require('scale-ts');
15
15
  var bip32 = require('@scure/bip32');
16
16
  var hmac = require('@noble/hashes/hmac');
17
17
  var sha512 = require('@noble/hashes/sha512');
18
- var microSr25519 = require('micro-sr25519');
18
+ var sr25519 = require('@scure/sr25519');
19
+ var chacha_js = require('@noble/ciphers/chacha.js');
20
+ var utils_js = require('@noble/ciphers/utils.js');
21
+ var mlkem = require('mlkem');
19
22
 
20
23
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
21
24
 
@@ -568,10 +571,13 @@ const getPublicKeySolana = secretKey => {
568
571
  const deriveSr25519 = (seed, derivationPath) => {
569
572
  const derivations = parseSubstrateDerivations(derivationPath);
570
573
  const secretKey = derivations.reduce((secretKey, [type, chainCode]) => {
571
- const deriveFn = type === "hard" ? microSr25519.HDKD.secretHard : microSr25519.HDKD.secretSoft;
574
+ const deriveFn = type === "hard" ? sr25519.HDKD.secretHard : sr25519.HDKD.secretSoft;
572
575
  const code = createChainCode(chainCode);
573
- return deriveFn(secretKey, code, utils.randomBytes);
574
- }, microSr25519.secretFromSeed(seed));
576
+ if (type === "hard") return deriveFn(secretKey, code);
577
+
578
+ // Soft derivations need fresh randomness; @scure/sr25519 expects the bytes, not a generator
579
+ return deriveFn(secretKey, code, utils.randomBytes(32));
580
+ }, sr25519.secretFromSeed(seed));
575
581
  const publicKey = getPublicKeySr25519(secretKey);
576
582
  return {
577
583
  type: "sr25519",
@@ -580,7 +586,7 @@ const deriveSr25519 = (seed, derivationPath) => {
580
586
  address: addressFromPublicKey(publicKey, "ss58")
581
587
  };
582
588
  };
583
- const getPublicKeySr25519 = microSr25519.getPublicKey;
589
+ const getPublicKeySr25519 = sr25519.getPublicKey;
584
590
 
585
591
  const deriveKeypair = (seed, derivationPath, curve) => {
586
592
  switch (curve) {
@@ -700,6 +706,20 @@ const getAccountPlatformFromAddress = address => {
700
706
  return getAccountPlatformFromEncoding(encoding);
701
707
  };
702
708
 
709
+ const encryptKemAead = async (publicKey, plaintext) => {
710
+ const kem = new mlkem.MlKem768();
711
+ const [kemCt, sharedSecret] = await kem.encap(publicKey);
712
+ if (sharedSecret.length !== 32) {
713
+ throw new Error(`Expected 32-byte shared secret, got ${sharedSecret.length}`);
714
+ }
715
+ const nonce = crypto.getRandomValues(new Uint8Array(24));
716
+ const aead = chacha_js.xchacha20poly1305(sharedSecret, nonce);
717
+ const aeadCt = aead.encrypt(plaintext);
718
+ const kemLen = new Uint8Array(2);
719
+ new DataView(kemLen.buffer).setUint16(0, kemCt.length, true);
720
+ return utils_js.concatBytes(kemLen, kemCt, nonce, aeadCt);
721
+ };
722
+
703
723
  Object.defineProperty(exports, "base58", {
704
724
  enumerable: true,
705
725
  get: function () { return base.base58; }
@@ -736,6 +756,7 @@ exports.encodeAddressEthereum = encodeAddressEthereum;
736
756
  exports.encodeAddressSolana = encodeAddressSolana;
737
757
  exports.encodeAddressSs58 = encodeAddressSs58;
738
758
  exports.encodeAnyAddress = encodeAnyAddress;
759
+ exports.encryptKemAead = encryptKemAead;
739
760
  exports.entropyToMnemonic = entropyToMnemonic;
740
761
  exports.entropyToSeed = entropyToSeed;
741
762
  exports.fromBase58Check = fromBase58Check;
@@ -15,7 +15,10 @@ var scaleTs = require('scale-ts');
15
15
  var bip32 = require('@scure/bip32');
16
16
  var hmac = require('@noble/hashes/hmac');
17
17
  var sha512 = require('@noble/hashes/sha512');
18
- var microSr25519 = require('micro-sr25519');
18
+ var sr25519 = require('@scure/sr25519');
19
+ var chacha_js = require('@noble/ciphers/chacha.js');
20
+ var utils_js = require('@noble/ciphers/utils.js');
21
+ var mlkem = require('mlkem');
19
22
 
20
23
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
21
24
 
@@ -568,10 +571,13 @@ const getPublicKeySolana = secretKey => {
568
571
  const deriveSr25519 = (seed, derivationPath) => {
569
572
  const derivations = parseSubstrateDerivations(derivationPath);
570
573
  const secretKey = derivations.reduce((secretKey, [type, chainCode]) => {
571
- const deriveFn = type === "hard" ? microSr25519.HDKD.secretHard : microSr25519.HDKD.secretSoft;
574
+ const deriveFn = type === "hard" ? sr25519.HDKD.secretHard : sr25519.HDKD.secretSoft;
572
575
  const code = createChainCode(chainCode);
573
- return deriveFn(secretKey, code, utils.randomBytes);
574
- }, microSr25519.secretFromSeed(seed));
576
+ if (type === "hard") return deriveFn(secretKey, code);
577
+
578
+ // Soft derivations need fresh randomness; @scure/sr25519 expects the bytes, not a generator
579
+ return deriveFn(secretKey, code, utils.randomBytes(32));
580
+ }, sr25519.secretFromSeed(seed));
575
581
  const publicKey = getPublicKeySr25519(secretKey);
576
582
  return {
577
583
  type: "sr25519",
@@ -580,7 +586,7 @@ const deriveSr25519 = (seed, derivationPath) => {
580
586
  address: addressFromPublicKey(publicKey, "ss58")
581
587
  };
582
588
  };
583
- const getPublicKeySr25519 = microSr25519.getPublicKey;
589
+ const getPublicKeySr25519 = sr25519.getPublicKey;
584
590
 
585
591
  const deriveKeypair = (seed, derivationPath, curve) => {
586
592
  switch (curve) {
@@ -700,6 +706,20 @@ const getAccountPlatformFromAddress = address => {
700
706
  return getAccountPlatformFromEncoding(encoding);
701
707
  };
702
708
 
709
+ const encryptKemAead = async (publicKey, plaintext) => {
710
+ const kem = new mlkem.MlKem768();
711
+ const [kemCt, sharedSecret] = await kem.encap(publicKey);
712
+ if (sharedSecret.length !== 32) {
713
+ throw new Error(`Expected 32-byte shared secret, got ${sharedSecret.length}`);
714
+ }
715
+ const nonce = crypto.getRandomValues(new Uint8Array(24));
716
+ const aead = chacha_js.xchacha20poly1305(sharedSecret, nonce);
717
+ const aeadCt = aead.encrypt(plaintext);
718
+ const kemLen = new Uint8Array(2);
719
+ new DataView(kemLen.buffer).setUint16(0, kemCt.length, true);
720
+ return utils_js.concatBytes(kemLen, kemCt, nonce, aeadCt);
721
+ };
722
+
703
723
  Object.defineProperty(exports, "base58", {
704
724
  enumerable: true,
705
725
  get: function () { return base.base58; }
@@ -736,6 +756,7 @@ exports.encodeAddressEthereum = encodeAddressEthereum;
736
756
  exports.encodeAddressSolana = encodeAddressSolana;
737
757
  exports.encodeAddressSs58 = encodeAddressSs58;
738
758
  exports.encodeAnyAddress = encodeAnyAddress;
759
+ exports.encryptKemAead = encryptKemAead;
739
760
  exports.entropyToMnemonic = entropyToMnemonic;
740
761
  exports.entropyToSeed = entropyToSeed;
741
762
  exports.fromBase58Check = fromBase58Check;
@@ -15,7 +15,10 @@ import { Tuple, str, Bytes, u32 } from 'scale-ts';
15
15
  import { HDKey } from '@scure/bip32';
16
16
  import { hmac } from '@noble/hashes/hmac';
17
17
  import { sha512 } from '@noble/hashes/sha512';
18
- import { getPublicKey, HDKD, secretFromSeed } from 'micro-sr25519';
18
+ import { getPublicKey, HDKD, secretFromSeed } from '@scure/sr25519';
19
+ import { xchacha20poly1305 } from '@noble/ciphers/chacha.js';
20
+ import { concatBytes } from '@noble/ciphers/utils.js';
21
+ import { MlKem768 } from 'mlkem';
19
22
 
20
23
  const pbkdf2 = async (hash, entropy, salt, iterations, outputLenBytes) => {
21
24
  // NOTE: react-native-quick-crypto (our `global.crypto` polyfill on Talisman Mobile) doesn't support `crypto.subtle.deriveKey`.
@@ -566,7 +569,10 @@ const deriveSr25519 = (seed, derivationPath) => {
566
569
  const secretKey = derivations.reduce((secretKey, [type, chainCode]) => {
567
570
  const deriveFn = type === "hard" ? HDKD.secretHard : HDKD.secretSoft;
568
571
  const code = createChainCode(chainCode);
569
- return deriveFn(secretKey, code, randomBytes);
572
+ if (type === "hard") return deriveFn(secretKey, code);
573
+
574
+ // Soft derivations need fresh randomness; @scure/sr25519 expects the bytes, not a generator
575
+ return deriveFn(secretKey, code, randomBytes(32));
570
576
  }, secretFromSeed(seed));
571
577
  const publicKey = getPublicKeySr25519(secretKey);
572
578
  return {
@@ -696,4 +702,18 @@ const getAccountPlatformFromAddress = address => {
696
702
  return getAccountPlatformFromEncoding(encoding);
697
703
  };
698
704
 
699
- export { DEV_MNEMONIC_ETHEREUM, DEV_MNEMONIC_POLKADOT, addressEncodingFromCurve, addressFromMnemonic, addressFromPublicKey, blake2b256, blake2b512, blake3, checksumEthereumAddress, decodeSs58Address, deriveKeypair, detectAddressEncoding, encodeAddressEthereum, encodeAddressSolana, encodeAddressSs58, encodeAnyAddress, entropyToMnemonic, entropyToSeed, fromBase58Check, fromBech32, fromBech32m, generateMnemonic, getAccountPlatformFromAddress, getAccountPlatformFromCurve, getAccountPlatformFromEncoding, getDevSeed, getPublicKeyFromSecret, getSafeHash, isAddressEqual, isAddressValid, isBase58CheckAddress, isBech32Address, isBech32mAddress, isBitcoinAddress, isEthereumAddress, isSolanaAddress, isSs58Address, isValidDerivationPath, isValidMnemonic, mnemonicToEntropy, normalizeAddress, parseSecretKey, pbkdf2, removeHexPrefix };
705
+ const encryptKemAead = async (publicKey, plaintext) => {
706
+ const kem = new MlKem768();
707
+ const [kemCt, sharedSecret] = await kem.encap(publicKey);
708
+ if (sharedSecret.length !== 32) {
709
+ throw new Error(`Expected 32-byte shared secret, got ${sharedSecret.length}`);
710
+ }
711
+ const nonce = crypto.getRandomValues(new Uint8Array(24));
712
+ const aead = xchacha20poly1305(sharedSecret, nonce);
713
+ const aeadCt = aead.encrypt(plaintext);
714
+ const kemLen = new Uint8Array(2);
715
+ new DataView(kemLen.buffer).setUint16(0, kemCt.length, true);
716
+ return concatBytes(kemLen, kemCt, nonce, aeadCt);
717
+ };
718
+
719
+ export { DEV_MNEMONIC_ETHEREUM, DEV_MNEMONIC_POLKADOT, addressEncodingFromCurve, addressFromMnemonic, addressFromPublicKey, blake2b256, blake2b512, blake3, checksumEthereumAddress, decodeSs58Address, deriveKeypair, detectAddressEncoding, encodeAddressEthereum, encodeAddressSolana, encodeAddressSs58, encodeAnyAddress, encryptKemAead, entropyToMnemonic, entropyToSeed, fromBase58Check, fromBech32, fromBech32m, generateMnemonic, getAccountPlatformFromAddress, getAccountPlatformFromCurve, getAccountPlatformFromEncoding, getDevSeed, getPublicKeyFromSecret, getSafeHash, isAddressEqual, isAddressValid, isBase58CheckAddress, isBech32Address, isBech32mAddress, isBitcoinAddress, isEthereumAddress, isSolanaAddress, isSs58Address, isValidDerivationPath, isValidMnemonic, mnemonicToEntropy, normalizeAddress, parseSecretKey, pbkdf2, removeHexPrefix };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@talismn/crypto",
3
- "version": "0.0.0-pr2183-20250930074110",
3
+ "version": "0.0.0-pr2275-20251210101511",
4
4
  "author": "Talisman",
5
5
  "homepage": "https://talisman.xyz",
6
6
  "license": "GPL-3.0-or-later",
@@ -21,14 +21,16 @@
21
21
  "node": ">=20"
22
22
  },
23
23
  "dependencies": {
24
+ "@noble/ciphers": "2.0.1",
24
25
  "@noble/curves": "1.9.2",
25
26
  "@noble/hashes": "1.8.0",
26
27
  "@scure/base": "1.2.6",
27
28
  "@scure/bip32": "1.7.0",
28
29
  "@scure/bip39": "1.5.4",
30
+ "@scure/sr25519": "1.0.0",
29
31
  "bech32": "2.0.0",
30
32
  "bs58check": "4.0.0",
31
- "micro-sr25519": "0.1.3",
33
+ "mlkem": "2.5.0",
32
34
  "scale-ts": "1.6.1"
33
35
  },
34
36
  "devDependencies": {
@@ -37,8 +39,8 @@
37
39
  "jest": "^29.7.0",
38
40
  "ts-jest": "^29.2.5",
39
41
  "typescript": "^5.6.3",
40
- "@talismn/tsconfig": "0.0.0-pr2183-20250930074110",
41
- "@talismn/eslint-config": "0.0.3"
42
+ "@talismn/eslint-config": "0.0.3",
43
+ "@talismn/tsconfig": "0.0.3"
42
44
  },
43
45
  "preconstruct": {
44
46
  "entrypoints": [