@bsv/sdk 1.9.31 → 2.0.0-beta.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/cjs/package.json +2 -3
- package/dist/cjs/src/auth/Peer.js +11 -18
- package/dist/cjs/src/auth/Peer.js.map +1 -1
- package/dist/cjs/src/auth/SessionManager.js.map +1 -1
- package/dist/cjs/src/auth/certificates/Certificate.js +8 -18
- package/dist/cjs/src/auth/certificates/Certificate.js.map +1 -1
- package/dist/cjs/src/auth/certificates/MasterCertificate.js +9 -19
- package/dist/cjs/src/auth/certificates/MasterCertificate.js.map +1 -1
- package/dist/cjs/src/auth/certificates/VerifiableCertificate.js +7 -17
- package/dist/cjs/src/auth/certificates/VerifiableCertificate.js.map +1 -1
- package/dist/cjs/src/auth/certificates/__tests/CompletedProtoWallet.js.map +1 -1
- package/dist/cjs/src/auth/clients/AuthFetch.js +7 -17
- package/dist/cjs/src/auth/clients/AuthFetch.js.map +1 -1
- package/dist/cjs/src/auth/clients/__tests__/AuthFetch.test.js.map +1 -1
- package/dist/cjs/src/auth/transports/SimplifiedFetchTransport.js +7 -17
- package/dist/cjs/src/auth/transports/SimplifiedFetchTransport.js.map +1 -1
- package/dist/cjs/src/auth/transports/__tests__/SimplifiedFetchTransport.test.js +7 -17
- package/dist/cjs/src/auth/transports/__tests__/SimplifiedFetchTransport.test.js.map +1 -1
- package/dist/cjs/src/auth/utils/createNonce.js +9 -18
- package/dist/cjs/src/auth/utils/createNonce.js.map +1 -1
- package/dist/cjs/src/auth/utils/validateCertificates.js.map +1 -1
- package/dist/cjs/src/auth/utils/verifyNonce.js +9 -18
- package/dist/cjs/src/auth/utils/verifyNonce.js.map +1 -1
- package/dist/cjs/src/compat/BSM.js +7 -17
- package/dist/cjs/src/compat/BSM.js.map +1 -1
- package/dist/cjs/src/compat/ECIES.js +7 -17
- package/dist/cjs/src/compat/ECIES.js.map +1 -1
- package/dist/cjs/src/compat/HD.js +7 -17
- package/dist/cjs/src/compat/HD.js.map +1 -1
- package/dist/cjs/src/compat/Mnemonic.js +7 -17
- package/dist/cjs/src/compat/Mnemonic.js.map +1 -1
- package/dist/cjs/src/compat/Utxo.js +1 -1
- package/dist/cjs/src/compat/Utxo.js.map +1 -1
- package/dist/cjs/src/compat/index.js +7 -17
- package/dist/cjs/src/compat/index.js.map +1 -1
- package/dist/cjs/src/identity/ContactsManager.js +1 -1
- package/dist/cjs/src/identity/ContactsManager.js.map +1 -1
- package/dist/cjs/src/identity/IdentityClient.js.map +1 -1
- package/dist/cjs/src/kvstore/GlobalKVStore.js +10 -20
- package/dist/cjs/src/kvstore/GlobalKVStore.js.map +1 -1
- package/dist/cjs/src/kvstore/LocalKVStore.js +7 -17
- package/dist/cjs/src/kvstore/LocalKVStore.js.map +1 -1
- package/dist/cjs/src/kvstore/kvStoreInterpreter.js +7 -17
- package/dist/cjs/src/kvstore/kvStoreInterpreter.js.map +1 -1
- package/dist/cjs/src/messages/EncryptedMessage.js +0 -19
- package/dist/cjs/src/messages/EncryptedMessage.js.map +1 -1
- package/dist/cjs/src/messages/SignedMessage.js.map +1 -1
- package/dist/cjs/src/messages/index.js +7 -17
- package/dist/cjs/src/messages/index.js.map +1 -1
- package/dist/cjs/src/overlay-tools/Historian.js.map +1 -1
- package/dist/cjs/src/overlay-tools/HostReputationTracker.js.map +1 -1
- package/dist/cjs/src/overlay-tools/LookupResolver.js +7 -17
- package/dist/cjs/src/overlay-tools/LookupResolver.js.map +1 -1
- package/dist/cjs/src/overlay-tools/OverlayAdminTokenTemplate.js.map +1 -1
- package/dist/cjs/src/overlay-tools/SHIPBroadcaster.js +7 -17
- package/dist/cjs/src/overlay-tools/SHIPBroadcaster.js.map +1 -1
- package/dist/cjs/src/overlay-tools/withDoubleSpendRetry.js +2 -1
- package/dist/cjs/src/overlay-tools/withDoubleSpendRetry.js.map +1 -1
- package/dist/cjs/src/primitives/AESGCM.js +32 -77
- package/dist/cjs/src/primitives/AESGCM.js.map +1 -1
- package/dist/cjs/src/primitives/BigNumber.js.map +1 -1
- package/dist/cjs/src/primitives/Curve.js.map +1 -1
- package/dist/cjs/src/primitives/DRBG.js.map +1 -1
- package/dist/cjs/src/primitives/ECDSA.js +23 -22
- package/dist/cjs/src/primitives/ECDSA.js.map +1 -1
- package/dist/cjs/src/primitives/Hash.js +6 -6
- package/dist/cjs/src/primitives/Hash.js.map +1 -1
- package/dist/cjs/src/primitives/JacobianPoint.js.map +1 -1
- package/dist/cjs/src/primitives/K256.js.map +1 -1
- package/dist/cjs/src/primitives/Mersenne.js.map +1 -1
- package/dist/cjs/src/primitives/MontgomoryMethod.js.map +1 -1
- package/dist/cjs/src/primitives/Point.js +6 -63
- package/dist/cjs/src/primitives/Point.js.map +1 -1
- package/dist/cjs/src/primitives/Polynomial.js.map +1 -1
- package/dist/cjs/src/primitives/PrivateKey.js +9 -46
- package/dist/cjs/src/primitives/PrivateKey.js.map +1 -1
- package/dist/cjs/src/primitives/PublicKey.js +1 -1
- package/dist/cjs/src/primitives/PublicKey.js.map +1 -1
- package/dist/cjs/src/primitives/Random.js.map +1 -1
- package/dist/cjs/src/primitives/ReductionContext.js.map +1 -1
- package/dist/cjs/src/primitives/Schnorr.js.map +1 -1
- package/dist/cjs/src/primitives/Secp256r1.js.map +1 -1
- package/dist/cjs/src/primitives/Signature.js.map +1 -1
- package/dist/cjs/src/primitives/SymmetricKey.js.map +1 -1
- package/dist/cjs/src/primitives/TransactionSignature.js +7 -17
- package/dist/cjs/src/primitives/TransactionSignature.js.map +1 -1
- package/dist/cjs/src/primitives/hex.js +3 -2
- package/dist/cjs/src/primitives/hex.js.map +1 -1
- package/dist/cjs/src/primitives/index.js +7 -17
- package/dist/cjs/src/primitives/index.js.map +1 -1
- package/dist/cjs/src/primitives/utils.js +15 -123
- package/dist/cjs/src/primitives/utils.js.map +1 -1
- package/dist/cjs/src/registry/RegistryClient.js +2 -2
- package/dist/cjs/src/registry/RegistryClient.js.map +1 -1
- package/dist/cjs/src/script/OP.js +3 -3
- package/dist/cjs/src/script/OP.js.map +1 -1
- package/dist/cjs/src/script/Script.js.map +1 -1
- package/dist/cjs/src/script/Spend.js +7 -17
- package/dist/cjs/src/script/Spend.js.map +1 -1
- package/dist/cjs/src/script/templates/P2PKH.js.map +1 -1
- package/dist/cjs/src/script/templates/PushDrop.js.map +1 -1
- package/dist/cjs/src/script/templates/RPuzzle.js.map +1 -1
- package/dist/cjs/src/storage/StorageDownloader.js.map +1 -1
- package/dist/cjs/src/storage/StorageUploader.js +7 -17
- package/dist/cjs/src/storage/StorageUploader.js.map +1 -1
- package/dist/cjs/src/storage/StorageUtils.js.map +1 -1
- package/dist/cjs/src/storage/__test/StorageDownloader.test.js +171 -0
- package/dist/cjs/src/storage/__test/StorageDownloader.test.js.map +1 -0
- package/dist/cjs/src/storage/__test/StorageUploader.test.js +163 -0
- package/dist/cjs/src/storage/__test/StorageUploader.test.js.map +1 -0
- package/dist/cjs/src/storage/__test/StorageUtils.test.js +97 -0
- package/dist/cjs/src/storage/__test/StorageUtils.test.js.map +1 -0
- package/dist/cjs/src/storage/index.js +7 -17
- package/dist/cjs/src/storage/index.js.map +1 -1
- package/dist/cjs/src/totp/totp.js.map +1 -1
- package/dist/cjs/src/transaction/Beef.js.map +1 -1
- package/dist/cjs/src/transaction/BeefParty.js.map +1 -1
- package/dist/cjs/src/transaction/BeefTx.js.map +1 -1
- package/dist/cjs/src/transaction/Broadcaster.js +3 -2
- package/dist/cjs/src/transaction/Broadcaster.js.map +1 -1
- package/dist/cjs/src/transaction/MerklePath.js.map +1 -1
- package/dist/cjs/src/transaction/Transaction.js +1 -1
- package/dist/cjs/src/transaction/Transaction.js.map +1 -1
- package/dist/cjs/src/transaction/broadcasters/ARC.js.map +1 -1
- package/dist/cjs/src/transaction/broadcasters/DefaultBroadcaster.js +2 -1
- package/dist/cjs/src/transaction/broadcasters/DefaultBroadcaster.js.map +1 -1
- package/dist/cjs/src/transaction/broadcasters/Teranode.js.map +1 -1
- package/dist/cjs/src/transaction/broadcasters/WhatsOnChainBroadcaster.js.map +1 -1
- package/dist/cjs/src/transaction/chaintrackers/BlockHeadersService.js.map +1 -1
- package/dist/cjs/src/transaction/chaintrackers/DefaultChainTracker.js +2 -1
- package/dist/cjs/src/transaction/chaintrackers/DefaultChainTracker.js.map +1 -1
- package/dist/cjs/src/transaction/chaintrackers/WhatsOnChain.js.map +1 -1
- package/dist/cjs/src/transaction/fee-models/LivePolicy.js.map +1 -1
- package/dist/cjs/src/transaction/fee-models/SatoshisPerKilobyte.js.map +1 -1
- package/dist/cjs/src/transaction/http/BinaryFetchClient.js +2 -2
- package/dist/cjs/src/transaction/http/BinaryFetchClient.js.map +1 -1
- package/dist/cjs/src/transaction/http/DefaultHttpClient.js +2 -1
- package/dist/cjs/src/transaction/http/DefaultHttpClient.js.map +1 -1
- package/dist/cjs/src/transaction/http/NodejsHttpClient.js.map +1 -1
- package/dist/cjs/src/wallet/CachedKeyDeriver.js.map +1 -1
- package/dist/cjs/src/wallet/KeyDeriver.js.map +1 -1
- package/dist/cjs/src/wallet/ProtoWallet.js +1 -1
- package/dist/cjs/src/wallet/ProtoWallet.js.map +1 -1
- package/dist/cjs/src/wallet/WalletClient.js.map +1 -1
- package/dist/cjs/src/wallet/WalletError.js.map +1 -1
- package/dist/cjs/src/wallet/index.js +7 -17
- package/dist/cjs/src/wallet/index.js.map +1 -1
- package/dist/cjs/src/wallet/substrates/HTTPWalletJSON.js.map +1 -1
- package/dist/cjs/src/wallet/substrates/HTTPWalletWire.js +7 -17
- package/dist/cjs/src/wallet/substrates/HTTPWalletWire.js.map +1 -1
- package/dist/cjs/src/wallet/substrates/ReactNativeWebView.js +7 -17
- package/dist/cjs/src/wallet/substrates/ReactNativeWebView.js.map +1 -1
- package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js +7 -17
- package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js.map +1 -1
- package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js +7 -17
- package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js.map +1 -1
- package/dist/cjs/src/wallet/substrates/XDM.js +7 -17
- package/dist/cjs/src/wallet/substrates/XDM.js.map +1 -1
- package/dist/cjs/src/wallet/substrates/utils/toOriginHeader.js +2 -1
- package/dist/cjs/src/wallet/substrates/utils/toOriginHeader.js.map +1 -1
- package/dist/cjs/src/wallet/substrates/window.CWI.js.map +1 -1
- package/dist/cjs/src/wallet/validationHelpers.js +41 -51
- package/dist/cjs/src/wallet/validationHelpers.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/auth/Peer.js +4 -1
- package/dist/esm/src/auth/Peer.js.map +1 -1
- package/dist/esm/src/auth/SessionManager.js.map +1 -1
- package/dist/esm/src/auth/certificates/Certificate.js +1 -1
- package/dist/esm/src/auth/certificates/Certificate.js.map +1 -1
- package/dist/esm/src/auth/certificates/MasterCertificate.js +2 -2
- package/dist/esm/src/auth/certificates/MasterCertificate.js.map +1 -1
- package/dist/esm/src/auth/certificates/VerifiableCertificate.js.map +1 -1
- package/dist/esm/src/auth/certificates/__tests/CompletedProtoWallet.js.map +1 -1
- package/dist/esm/src/auth/clients/AuthFetch.js.map +1 -1
- package/dist/esm/src/auth/clients/__tests__/AuthFetch.test.js.map +1 -1
- package/dist/esm/src/auth/transports/SimplifiedFetchTransport.js.map +1 -1
- package/dist/esm/src/auth/transports/__tests__/SimplifiedFetchTransport.test.js.map +1 -1
- package/dist/esm/src/auth/utils/validateCertificates.js.map +1 -1
- package/dist/esm/src/compat/BSM.js.map +1 -1
- package/dist/esm/src/compat/ECIES.js.map +1 -1
- package/dist/esm/src/compat/HD.js.map +1 -1
- package/dist/esm/src/compat/Mnemonic.js.map +1 -1
- package/dist/esm/src/identity/ContactsManager.js +1 -1
- package/dist/esm/src/identity/ContactsManager.js.map +1 -1
- package/dist/esm/src/identity/IdentityClient.js.map +1 -1
- package/dist/esm/src/kvstore/GlobalKVStore.js +3 -3
- package/dist/esm/src/kvstore/GlobalKVStore.js.map +1 -1
- package/dist/esm/src/kvstore/LocalKVStore.js.map +1 -1
- package/dist/esm/src/kvstore/kvStoreInterpreter.js.map +1 -1
- package/dist/esm/src/messages/EncryptedMessage.js +0 -19
- package/dist/esm/src/messages/EncryptedMessage.js.map +1 -1
- package/dist/esm/src/messages/SignedMessage.js.map +1 -1
- package/dist/esm/src/overlay-tools/Historian.js.map +1 -1
- package/dist/esm/src/overlay-tools/HostReputationTracker.js.map +1 -1
- package/dist/esm/src/overlay-tools/LookupResolver.js.map +1 -1
- package/dist/esm/src/overlay-tools/OverlayAdminTokenTemplate.js.map +1 -1
- package/dist/esm/src/overlay-tools/SHIPBroadcaster.js.map +1 -1
- package/dist/esm/src/overlay-tools/withDoubleSpendRetry.js.map +1 -1
- package/dist/esm/src/primitives/AESGCM.js +26 -71
- package/dist/esm/src/primitives/AESGCM.js.map +1 -1
- package/dist/esm/src/primitives/BigNumber.js.map +1 -1
- package/dist/esm/src/primitives/Curve.js.map +1 -1
- package/dist/esm/src/primitives/DRBG.js.map +1 -1
- package/dist/esm/src/primitives/ECDSA.js +23 -22
- package/dist/esm/src/primitives/ECDSA.js.map +1 -1
- package/dist/esm/src/primitives/Hash.js.map +1 -1
- package/dist/esm/src/primitives/JacobianPoint.js.map +1 -1
- package/dist/esm/src/primitives/K256.js.map +1 -1
- package/dist/esm/src/primitives/Mersenne.js.map +1 -1
- package/dist/esm/src/primitives/MontgomoryMethod.js.map +1 -1
- package/dist/esm/src/primitives/Point.js +4 -61
- package/dist/esm/src/primitives/Point.js.map +1 -1
- package/dist/esm/src/primitives/Polynomial.js.map +1 -1
- package/dist/esm/src/primitives/PrivateKey.js +2 -29
- package/dist/esm/src/primitives/PrivateKey.js.map +1 -1
- package/dist/esm/src/primitives/PublicKey.js +1 -1
- package/dist/esm/src/primitives/PublicKey.js.map +1 -1
- package/dist/esm/src/primitives/Random.js.map +1 -1
- package/dist/esm/src/primitives/ReductionContext.js.map +1 -1
- package/dist/esm/src/primitives/Schnorr.js.map +1 -1
- package/dist/esm/src/primitives/Secp256r1.js.map +1 -1
- package/dist/esm/src/primitives/Signature.js.map +1 -1
- package/dist/esm/src/primitives/SymmetricKey.js.map +1 -1
- package/dist/esm/src/primitives/TransactionSignature.js.map +1 -1
- package/dist/esm/src/primitives/hex.js.map +1 -1
- package/dist/esm/src/primitives/utils.js +10 -118
- package/dist/esm/src/primitives/utils.js.map +1 -1
- package/dist/esm/src/registry/RegistryClient.js.map +1 -1
- package/dist/esm/src/script/OP.js +3 -3
- package/dist/esm/src/script/OP.js.map +1 -1
- package/dist/esm/src/script/Script.js.map +1 -1
- package/dist/esm/src/script/Spend.js.map +1 -1
- package/dist/esm/src/script/templates/P2PKH.js.map +1 -1
- package/dist/esm/src/script/templates/PushDrop.js.map +1 -1
- package/dist/esm/src/script/templates/RPuzzle.js.map +1 -1
- package/dist/esm/src/storage/StorageDownloader.js.map +1 -1
- package/dist/esm/src/storage/StorageUploader.js.map +1 -1
- package/dist/esm/src/storage/StorageUtils.js.map +1 -1
- package/dist/esm/src/storage/__test/StorageDownloader.test.js +166 -0
- package/dist/esm/src/storage/__test/StorageDownloader.test.js.map +1 -0
- package/dist/esm/src/storage/__test/StorageUploader.test.js +135 -0
- package/dist/esm/src/storage/__test/StorageUploader.test.js.map +1 -0
- package/dist/esm/src/storage/__test/StorageUtils.test.js +72 -0
- package/dist/esm/src/storage/__test/StorageUtils.test.js.map +1 -0
- package/dist/esm/src/totp/totp.js.map +1 -1
- package/dist/esm/src/transaction/Beef.js.map +1 -1
- package/dist/esm/src/transaction/BeefParty.js.map +1 -1
- package/dist/esm/src/transaction/BeefTx.js.map +1 -1
- package/dist/esm/src/transaction/MerklePath.js.map +1 -1
- package/dist/esm/src/transaction/Transaction.js +1 -1
- package/dist/esm/src/transaction/Transaction.js.map +1 -1
- package/dist/esm/src/transaction/broadcasters/ARC.js.map +1 -1
- package/dist/esm/src/transaction/broadcasters/Teranode.js.map +1 -1
- package/dist/esm/src/transaction/broadcasters/WhatsOnChainBroadcaster.js.map +1 -1
- package/dist/esm/src/transaction/chaintrackers/BlockHeadersService.js.map +1 -1
- package/dist/esm/src/transaction/chaintrackers/WhatsOnChain.js.map +1 -1
- package/dist/esm/src/transaction/fee-models/LivePolicy.js.map +1 -1
- package/dist/esm/src/transaction/fee-models/SatoshisPerKilobyte.js.map +1 -1
- package/dist/esm/src/transaction/http/BinaryFetchClient.js.map +1 -1
- package/dist/esm/src/transaction/http/DefaultHttpClient.js.map +1 -1
- package/dist/esm/src/transaction/http/NodejsHttpClient.js.map +1 -1
- package/dist/esm/src/wallet/CachedKeyDeriver.js.map +1 -1
- package/dist/esm/src/wallet/KeyDeriver.js.map +1 -1
- package/dist/esm/src/wallet/ProtoWallet.js +1 -1
- package/dist/esm/src/wallet/ProtoWallet.js.map +1 -1
- package/dist/esm/src/wallet/WalletClient.js.map +1 -1
- package/dist/esm/src/wallet/WalletError.js.map +1 -1
- package/dist/esm/src/wallet/substrates/HTTPWalletJSON.js.map +1 -1
- package/dist/esm/src/wallet/substrates/HTTPWalletWire.js.map +1 -1
- package/dist/esm/src/wallet/substrates/ReactNativeWebView.js.map +1 -1
- package/dist/esm/src/wallet/substrates/WalletWireProcessor.js.map +1 -1
- package/dist/esm/src/wallet/substrates/WalletWireTransceiver.js.map +1 -1
- package/dist/esm/src/wallet/substrates/XDM.js.map +1 -1
- package/dist/esm/src/wallet/substrates/utils/toOriginHeader.js.map +1 -1
- package/dist/esm/src/wallet/substrates/window.CWI.js.map +1 -1
- package/dist/esm/src/wallet/validationHelpers.js +1 -1
- package/dist/esm/src/wallet/validationHelpers.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/auth/Peer.d.ts.map +1 -1
- package/dist/types/src/auth/certificates/MasterCertificate.d.ts.map +1 -1
- package/dist/types/src/auth/utils/getVerifiableCertificates.d.ts.map +1 -1
- package/dist/types/src/auth/utils/validateCertificates.d.ts.map +1 -1
- package/dist/types/src/compat/BSM.d.ts +1 -1
- package/dist/types/src/compat/BSM.d.ts.map +1 -1
- package/dist/types/src/messages/EncryptedMessage.d.ts +0 -19
- package/dist/types/src/messages/EncryptedMessage.d.ts.map +1 -1
- package/dist/types/src/messages/SignedMessage.d.ts.map +1 -1
- package/dist/types/src/primitives/AESGCM.d.ts +0 -18
- package/dist/types/src/primitives/AESGCM.d.ts.map +1 -1
- package/dist/types/src/primitives/ECDSA.d.ts.map +1 -1
- package/dist/types/src/primitives/Hash.d.ts +8 -8
- package/dist/types/src/primitives/Hash.d.ts.map +1 -1
- package/dist/types/src/primitives/Point.d.ts +0 -1
- package/dist/types/src/primitives/Point.d.ts.map +1 -1
- package/dist/types/src/primitives/PrivateKey.d.ts +0 -27
- package/dist/types/src/primitives/PrivateKey.d.ts.map +1 -1
- package/dist/types/src/primitives/Random.d.ts.map +1 -1
- package/dist/types/src/primitives/Secp256r1.d.ts.map +1 -1
- package/dist/types/src/primitives/utils.d.ts +3 -3
- package/dist/types/src/primitives/utils.d.ts.map +1 -1
- package/dist/types/src/storage/StorageUtils.d.ts.map +1 -1
- package/dist/types/src/storage/__test/StorageDownloader.test.d.ts +2 -0
- package/dist/types/src/storage/__test/StorageDownloader.test.d.ts.map +1 -0
- package/dist/types/src/storage/__test/StorageUploader.test.d.ts +2 -0
- package/dist/types/src/storage/__test/StorageUploader.test.d.ts.map +1 -0
- package/dist/types/src/storage/__test/StorageUtils.test.d.ts +2 -0
- package/dist/types/src/storage/__test/StorageUtils.test.d.ts.map +1 -0
- package/dist/types/src/transaction/Beef.d.ts +2 -2
- package/dist/types/src/transaction/Beef.d.ts.map +1 -1
- package/dist/types/src/transaction/http/BinaryFetchClient.d.ts +2 -0
- package/dist/types/src/transaction/http/BinaryFetchClient.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/umd/bundle.js +3 -3
- package/dist/umd/bundle.js.map +1 -1
- package/docs/reference/messages.md +0 -24
- package/docs/reference/primitives.md +17 -82
- package/package.json +2 -3
- package/src/auth/Peer.ts +4 -1
- package/src/messages/EncryptedMessage.ts +0 -19
- package/src/primitives/AESGCM.ts +34 -75
- package/src/primitives/PrivateKey.ts +0 -27
- package/src/primitives/__tests/AESGCM.test.ts +0 -31
- package/src/primitives/__tests/utils.test.ts +30 -7
- package/src/primitives/utils.ts +2 -127
|
@@ -2,30 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Variables](#variables)
|
|
4
4
|
|
|
5
|
-
## Security Considerations for Encrypted Messages
|
|
6
|
-
|
|
7
|
-
The encrypted message protocol implemented in this SDK derives per-message
|
|
8
|
-
encryption keys deterministically from the parties’ long-term keys and a
|
|
9
|
-
caller-supplied invoice number (BRC-42 style derivation).
|
|
10
|
-
|
|
11
|
-
This construction does **not** provide the guarantees of a standard
|
|
12
|
-
authenticated key exchange (AKE). In particular:
|
|
13
|
-
|
|
14
|
-
- **No forward secrecy**: Compromise of a long-term private key compromises
|
|
15
|
-
all past and future messages derived from it.
|
|
16
|
-
- **No replay protection**: Messages encrypted under the same invoice number
|
|
17
|
-
and key pair can be replayed.
|
|
18
|
-
- **Potential identity misbinding**: Public keys alone do not guarantee peer
|
|
19
|
-
identity without additional authentication or identity verification.
|
|
20
|
-
|
|
21
|
-
This protocol is intended for lightweight, deterministic messaging between
|
|
22
|
-
parties that already trust each other’s long-term public keys. It SHOULD NOT
|
|
23
|
-
be used for high-security or high-value communications without additional
|
|
24
|
-
protocol-layer protections.
|
|
25
|
-
|
|
26
|
-
Applications requiring strong authentication, replay protection, or forward
|
|
27
|
-
secrecy should use a formally analyzed protocol such as X3DH, Noise, or SIGMA.
|
|
28
|
-
|
|
29
5
|
## Interfaces
|
|
30
6
|
|
|
31
7
|
## Classes
|
|
@@ -4961,14 +4961,14 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
|
|
|
4961
4961
|
|
|
4962
4962
|
| | |
|
|
4963
4963
|
| --- | --- |
|
|
4964
|
-
| [AES](#function-aes) | [
|
|
4965
|
-
| [AESGCM](#function-aesgcm) | [
|
|
4966
|
-
| [AESGCMDecrypt](#function-aesgcmdecrypt) | [
|
|
4967
|
-
| [assertValidHex](#function-assertvalidhex) | [
|
|
4968
|
-
| [base64ToArray](#function-base64toarray) | [
|
|
4964
|
+
| [AES](#function-aes) | [normalizeHex](#function-normalizehex) |
|
|
4965
|
+
| [AESGCM](#function-aesgcm) | [pbkdf2](#function-pbkdf2) |
|
|
4966
|
+
| [AESGCMDecrypt](#function-aesgcmdecrypt) | [realHtonl](#function-realhtonl) |
|
|
4967
|
+
| [assertValidHex](#function-assertvalidhex) | [red](#function-red) |
|
|
4968
|
+
| [base64ToArray](#function-base64toarray) | [swapBytes32](#function-swapbytes32) |
|
|
4969
|
+
| [constantTimeEquals](#function-constanttimeequals) | [toArray](#function-toarray) |
|
|
4969
4970
|
| [ghash](#function-ghash) | [toBase64](#function-tobase64) |
|
|
4970
4971
|
| [htonl](#function-htonl) | [verifyNotNull](#function-verifynotnull) |
|
|
4971
|
-
| [normalizeHex](#function-normalizehex) | |
|
|
4972
4972
|
|
|
4973
4973
|
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
|
|
4974
4974
|
|
|
@@ -5067,6 +5067,15 @@ export function base64ToArray(msg: string): number[]
|
|
|
5067
5067
|
|
|
5068
5068
|
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
|
|
5069
5069
|
|
|
5070
|
+
---
|
|
5071
|
+
### Function: constantTimeEquals
|
|
5072
|
+
|
|
5073
|
+
```ts
|
|
5074
|
+
export function constantTimeEquals(a: Uint8Array | number[], b: Uint8Array | number[]): boolean
|
|
5075
|
+
```
|
|
5076
|
+
|
|
5077
|
+
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
|
|
5078
|
+
|
|
5070
5079
|
---
|
|
5071
5080
|
### Function: ghash
|
|
5072
5081
|
|
|
@@ -5736,7 +5745,7 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
|
|
|
5736
5745
|
```ts
|
|
5737
5746
|
incrementLeastSignificantThirtyTwoBits = function (block: Bytes): Bytes {
|
|
5738
5747
|
const result = block.slice();
|
|
5739
|
-
for (let i = 15; i
|
|
5748
|
+
for (let i = 15; i > 11; i--) {
|
|
5740
5749
|
result[i] = (result[i] + 1) & 255;
|
|
5741
5750
|
if (result[i] !== 0) {
|
|
5742
5751
|
break;
|
|
@@ -6265,81 +6274,7 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
|
|
|
6265
6274
|
|
|
6266
6275
|
```ts
|
|
6267
6276
|
toUTF8 = (arr: number[]): string => {
|
|
6268
|
-
|
|
6269
|
-
const replacementChar = "\uFFFD";
|
|
6270
|
-
for (let i = 0; i < arr.length; i++) {
|
|
6271
|
-
const byte1 = arr[i];
|
|
6272
|
-
if (byte1 <= 127) {
|
|
6273
|
-
result += String.fromCharCode(byte1);
|
|
6274
|
-
continue;
|
|
6275
|
-
}
|
|
6276
|
-
const emitReplacement = (): void => {
|
|
6277
|
-
result += replacementChar;
|
|
6278
|
-
};
|
|
6279
|
-
if (byte1 >= 192 && byte1 <= 223) {
|
|
6280
|
-
if (i + 1 >= arr.length) {
|
|
6281
|
-
emitReplacement();
|
|
6282
|
-
continue;
|
|
6283
|
-
}
|
|
6284
|
-
const byte2 = arr[i + 1];
|
|
6285
|
-
if ((byte2 & 192) !== 128) {
|
|
6286
|
-
emitReplacement();
|
|
6287
|
-
i += 1;
|
|
6288
|
-
continue;
|
|
6289
|
-
}
|
|
6290
|
-
const codePoint = ((byte1 & 31) << 6) | (byte2 & 63);
|
|
6291
|
-
result += String.fromCharCode(codePoint);
|
|
6292
|
-
i += 1;
|
|
6293
|
-
continue;
|
|
6294
|
-
}
|
|
6295
|
-
if (byte1 >= 224 && byte1 <= 239) {
|
|
6296
|
-
if (i + 2 >= arr.length) {
|
|
6297
|
-
emitReplacement();
|
|
6298
|
-
continue;
|
|
6299
|
-
}
|
|
6300
|
-
const byte2 = arr[i + 1];
|
|
6301
|
-
const byte3 = arr[i + 2];
|
|
6302
|
-
if ((byte2 & 192) !== 128 || (byte3 & 192) !== 128) {
|
|
6303
|
-
emitReplacement();
|
|
6304
|
-
i += 2;
|
|
6305
|
-
continue;
|
|
6306
|
-
}
|
|
6307
|
-
const codePoint = ((byte1 & 15) << 12) |
|
|
6308
|
-
((byte2 & 63) << 6) |
|
|
6309
|
-
(byte3 & 63);
|
|
6310
|
-
result += String.fromCharCode(codePoint);
|
|
6311
|
-
i += 2;
|
|
6312
|
-
continue;
|
|
6313
|
-
}
|
|
6314
|
-
if (byte1 >= 240 && byte1 <= 247) {
|
|
6315
|
-
if (i + 3 >= arr.length) {
|
|
6316
|
-
emitReplacement();
|
|
6317
|
-
continue;
|
|
6318
|
-
}
|
|
6319
|
-
const byte2 = arr[i + 1];
|
|
6320
|
-
const byte3 = arr[i + 2];
|
|
6321
|
-
const byte4 = arr[i + 3];
|
|
6322
|
-
if ((byte2 & 192) !== 128 ||
|
|
6323
|
-
(byte3 & 192) !== 128 ||
|
|
6324
|
-
(byte4 & 192) !== 128) {
|
|
6325
|
-
emitReplacement();
|
|
6326
|
-
i += 3;
|
|
6327
|
-
continue;
|
|
6328
|
-
}
|
|
6329
|
-
const codePoint = ((byte1 & 7) << 18) |
|
|
6330
|
-
((byte2 & 63) << 12) |
|
|
6331
|
-
((byte3 & 63) << 6) |
|
|
6332
|
-
(byte4 & 63);
|
|
6333
|
-
const offset = codePoint - 65536;
|
|
6334
|
-
const highSurrogate = 55296 + (offset >> 10);
|
|
6335
|
-
const lowSurrogate = 56320 + (offset & 1023);
|
|
6336
|
-
result += String.fromCharCode(highSurrogate, lowSurrogate);
|
|
6337
|
-
i += 3;
|
|
6338
|
-
continue;
|
|
6339
|
-
}
|
|
6340
|
-
emitReplacement();
|
|
6341
|
-
}
|
|
6342
|
-
return result;
|
|
6277
|
+
return new TextDecoder().decode(new Uint8Array(arr));
|
|
6343
6278
|
}
|
|
6344
6279
|
```
|
|
6345
6280
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bsv/sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-beta.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "BSV Blockchain Software Development Kit",
|
|
6
6
|
"main": "dist/cjs/mod.js",
|
|
@@ -221,8 +221,7 @@
|
|
|
221
221
|
"prepublish": "npm run build",
|
|
222
222
|
"doc": "ts2md",
|
|
223
223
|
"docs:serve": "mkdocs serve",
|
|
224
|
-
"docs:build": "mkdocs build"
|
|
225
|
-
"test:ci": "npm run build && jest --forceExit"
|
|
224
|
+
"docs:build": "mkdocs build"
|
|
226
225
|
},
|
|
227
226
|
"repository": {
|
|
228
227
|
"type": "git",
|
package/src/auth/Peer.ts
CHANGED
|
@@ -525,7 +525,10 @@ export class Peer {
|
|
|
525
525
|
|
|
526
526
|
// Create signature
|
|
527
527
|
const { signature } = await this.wallet.createSignature({
|
|
528
|
-
data:
|
|
528
|
+
data: [
|
|
529
|
+
...Peer.base64ToBytes(message.initialNonce),
|
|
530
|
+
...Peer.base64ToBytes(sessionNonce)
|
|
531
|
+
],
|
|
529
532
|
protocolID: [2, 'auth message signature'],
|
|
530
533
|
keyID: `${message.initialNonce} ${sessionNonce}`,
|
|
531
534
|
counterparty: message.identityKey
|
|
@@ -14,25 +14,6 @@ const VERSION = '42421033'
|
|
|
14
14
|
*
|
|
15
15
|
* @returns The encrypted message
|
|
16
16
|
*/
|
|
17
|
-
/**
|
|
18
|
-
* SECURITY NOTE – NON-AUTHENTICATED KEY EXCHANGE
|
|
19
|
-
*
|
|
20
|
-
* This encrypted message protocol does NOT implement a formally authenticated
|
|
21
|
-
* key exchange (AKE). Session keys are deterministically derived from long-term
|
|
22
|
-
* identity keys and a sender-chosen invoice value.
|
|
23
|
-
*
|
|
24
|
-
* As a result, this protocol does NOT provide:
|
|
25
|
-
* - Forward secrecy
|
|
26
|
-
* - Replay protection
|
|
27
|
-
* - Explicit authentication of peer identity
|
|
28
|
-
*
|
|
29
|
-
* This scheme SHOULD NOT be used for high-value, long-lived, or sensitive
|
|
30
|
-
* communications. It is intended for lightweight messaging where both parties
|
|
31
|
-
* already possess each other's long-term public keys and accept these risks.
|
|
32
|
-
*
|
|
33
|
-
* Future versions may introduce a protocol upgrade based on a standard AKE
|
|
34
|
-
* (e.g. X3DH, Noise, or SIGMA).
|
|
35
|
-
*/
|
|
36
17
|
export const encrypt = (
|
|
37
18
|
message: number[],
|
|
38
19
|
sender: PrivateKey,
|
package/src/primitives/AESGCM.ts
CHANGED
|
@@ -1,31 +1,5 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
1
|
|
|
3
|
-
//
|
|
4
|
-
// Table-based AES is intentionally retained for performance.
|
|
5
|
-
// JavaScript runtimes (JIT, GC, speculative execution) cannot provide
|
|
6
|
-
// strong constant-time guarantees, and arithmetic-only AES implementations
|
|
7
|
-
// cause catastrophic performance degradation in practice.
|
|
8
|
-
//
|
|
9
|
-
// This implementation therefore prioritizes correctness, performance,
|
|
10
|
-
// and compatibility over attempting misleading "constant-time" behavior.
|
|
11
|
-
//
|
|
12
|
-
// Applications requiring strict side-channel resistance SHOULD use
|
|
13
|
-
// platform-native crypto APIs (e.g. WebCrypto) or audited native libraries.
|
|
14
|
-
/**
|
|
15
|
-
* SECURITY DISCLAIMER – AES-GCM IMPLEMENTATION
|
|
16
|
-
*
|
|
17
|
-
* This module provides a self-contained AES-GCM implementation intended for
|
|
18
|
-
* functional correctness and portability with minimal dependencies.
|
|
19
|
-
*
|
|
20
|
-
* While efforts are made to reduce timing side-channel leakage (e.g. avoiding
|
|
21
|
-
* secret-dependent branches in GHASH), JavaScript does not guarantee
|
|
22
|
-
* constant-time execution. As such, this implementation should not be used in
|
|
23
|
-
* environments where attackers can reliably measure fine-grained execution
|
|
24
|
-
* timing (e.g. shared hosts, co-resident VMs, or untrusted browser contexts).
|
|
25
|
-
*
|
|
26
|
-
* For high-assurance cryptographic use cases, prefer platform-provided
|
|
27
|
-
* WebCrypto APIs or well-audited constant-time libraries.
|
|
28
|
-
*/
|
|
2
|
+
// @ts-nocheck
|
|
29
3
|
const SBox = new Uint8Array([
|
|
30
4
|
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
|
31
5
|
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
|
|
@@ -44,7 +18,6 @@ const SBox = new Uint8Array([
|
|
|
44
18
|
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
|
|
45
19
|
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
|
|
46
20
|
])
|
|
47
|
-
|
|
48
21
|
const Rcon = [
|
|
49
22
|
[0x00, 0x00, 0x00, 0x00], [0x01, 0x00, 0x00, 0x00], [0x02, 0x00, 0x00, 0x00], [0x04, 0x00, 0x00, 0x00],
|
|
50
23
|
[0x08, 0x00, 0x00, 0x00], [0x10, 0x00, 0x00, 0x00], [0x20, 0x00, 0x00, 0x00], [0x40, 0x00, 0x00, 0x00],
|
|
@@ -59,20 +32,6 @@ for (let i = 0; i < 256; i++) {
|
|
|
59
32
|
mul3[i] = m2 ^ i
|
|
60
33
|
}
|
|
61
34
|
|
|
62
|
-
function mixColumnsFast (state: number[][]): void {
|
|
63
|
-
for (let c = 0; c < 4; c++) {
|
|
64
|
-
const s0 = state[0][c]
|
|
65
|
-
const s1 = state[1][c]
|
|
66
|
-
const s2 = state[2][c]
|
|
67
|
-
const s3 = state[3][c]
|
|
68
|
-
|
|
69
|
-
state[0][c] = mul2[s0] ^ mul3[s1] ^ s2 ^ s3
|
|
70
|
-
state[1][c] = s0 ^ mul2[s1] ^ mul3[s2] ^ s3
|
|
71
|
-
state[2][c] = s0 ^ s1 ^ mul2[s2] ^ mul3[s3]
|
|
72
|
-
state[3][c] = mul3[s0] ^ s1 ^ s2 ^ mul2[s3]
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
35
|
function addRoundKey (
|
|
77
36
|
state: number[][],
|
|
78
37
|
roundKeyArray: number[][],
|
|
@@ -130,6 +89,20 @@ function shiftRows (state: number[][]): void {
|
|
|
130
89
|
state[3][0] = tmp
|
|
131
90
|
}
|
|
132
91
|
|
|
92
|
+
function mixColumns (state: number[][]): void {
|
|
93
|
+
for (let c = 0; c < 4; c++) {
|
|
94
|
+
const s0 = state[0][c]
|
|
95
|
+
const s1 = state[1][c]
|
|
96
|
+
const s2 = state[2][c]
|
|
97
|
+
const s3 = state[3][c]
|
|
98
|
+
|
|
99
|
+
state[0][c] = mul2[s0] ^ mul3[s1] ^ s2 ^ s3
|
|
100
|
+
state[1][c] = s0 ^ mul2[s1] ^ mul3[s2] ^ s3
|
|
101
|
+
state[2][c] = s0 ^ s1 ^ mul2[s2] ^ mul3[s3]
|
|
102
|
+
state[3][c] = mul3[s0] ^ s1 ^ s2 ^ mul2[s3]
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
133
106
|
function keyExpansion (roundLimit: number, key: number[]): number[][] {
|
|
134
107
|
const nK = key.length / 4
|
|
135
108
|
const result: number[][] = []
|
|
@@ -197,7 +170,7 @@ export function AES (input: number[], key: number[]): number[] {
|
|
|
197
170
|
shiftRows(state)
|
|
198
171
|
|
|
199
172
|
if (round + 1 < roundLimit) {
|
|
200
|
-
|
|
173
|
+
mixColumns(state)
|
|
201
174
|
}
|
|
202
175
|
|
|
203
176
|
addRoundKey(state, w, round * 4)
|
|
@@ -285,6 +258,12 @@ export const exclusiveOR = function (block0: Bytes, block1: Bytes): Bytes {
|
|
|
285
258
|
return result
|
|
286
259
|
}
|
|
287
260
|
|
|
261
|
+
const xorInto = function (target: Bytes, block: Bytes): void {
|
|
262
|
+
for (let i = 0; i < target.length; i++) {
|
|
263
|
+
target[i] ^= block[i] ?? 0
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
288
267
|
export const rightShift = function (block: Bytes): Bytes {
|
|
289
268
|
let carry = 0
|
|
290
269
|
let oldCarry = 0
|
|
@@ -302,48 +281,25 @@ export const rightShift = function (block: Bytes): Bytes {
|
|
|
302
281
|
return block
|
|
303
282
|
}
|
|
304
283
|
|
|
305
|
-
/**
|
|
306
|
-
* SECURITY NOTE – TIMING SIDE-CHANNEL MITIGATION
|
|
307
|
-
*
|
|
308
|
-
* This GHASH multiplication implementation avoids data-dependent conditional
|
|
309
|
-
* branches by using mask-based operations instead. This reduces timing
|
|
310
|
-
* side-channel leakage compared to a naive implementation that branches on
|
|
311
|
-
* secret bits.
|
|
312
|
-
*
|
|
313
|
-
* IMPORTANT: JavaScript and TypedArray operations do NOT provide constant-time
|
|
314
|
-
* execution guarantees. While this implementation mitigates obvious control-
|
|
315
|
-
* flow timing leaks, it must not be considered constant-time in a strict
|
|
316
|
-
* cryptographic sense and is not suitable for hostile shared-CPU or
|
|
317
|
-
* multi-tenant environments.
|
|
318
|
-
*
|
|
319
|
-
* Applications requiring strict constant-time AES-GCM SHOULD use a dedicated,
|
|
320
|
-
* audited cryptographic library (e.g. noble-ciphers, WebCrypto, or BearSSL
|
|
321
|
-
* bindings).
|
|
322
|
-
*/
|
|
323
284
|
export const multiply = function (block0: Bytes, block1: Bytes): Bytes {
|
|
324
285
|
const v = block1.slice()
|
|
325
286
|
const z = createZeroBlock(16)
|
|
326
287
|
|
|
327
288
|
for (let i = 0; i < 16; i++) {
|
|
328
|
-
const b = block0[i]
|
|
329
289
|
for (let j = 7; j >= 0; j--) {
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
const mask = -bit & 0xff
|
|
333
|
-
// z ^= v & mask
|
|
334
|
-
for (let k = 0; k < 16; k++) {
|
|
335
|
-
z[k] ^= v[k] & mask
|
|
290
|
+
if ((block0[i] & (1 << j)) !== 0) {
|
|
291
|
+
xorInto(z, v)
|
|
336
292
|
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
v[k] ^= R[k] & rmask
|
|
293
|
+
|
|
294
|
+
if ((v[15] & 1) !== 0) {
|
|
295
|
+
rightShift(v)
|
|
296
|
+
xorInto(v, R)
|
|
297
|
+
} else {
|
|
298
|
+
rightShift(v)
|
|
344
299
|
}
|
|
345
300
|
}
|
|
346
301
|
}
|
|
302
|
+
|
|
347
303
|
return z
|
|
348
304
|
}
|
|
349
305
|
|
|
@@ -351,12 +307,15 @@ export const incrementLeastSignificantThirtyTwoBits = function (
|
|
|
351
307
|
block: Bytes
|
|
352
308
|
): Bytes {
|
|
353
309
|
const result = block.slice()
|
|
310
|
+
|
|
354
311
|
for (let i = 15; i > 11; i--) {
|
|
355
312
|
result[i] = (result[i] + 1) & 0xff // wrap explicitly
|
|
313
|
+
|
|
356
314
|
if (result[i] !== 0) {
|
|
357
315
|
break
|
|
358
316
|
}
|
|
359
317
|
}
|
|
318
|
+
|
|
360
319
|
return result
|
|
361
320
|
}
|
|
362
321
|
|
|
@@ -355,33 +355,6 @@ export default class PrivateKey extends BigNumber {
|
|
|
355
355
|
return key.mulCT(this)
|
|
356
356
|
}
|
|
357
357
|
|
|
358
|
-
/**
|
|
359
|
-
* SECURITY NOTE – DETERMINISTIC CHILD KEY DERIVATION
|
|
360
|
-
*
|
|
361
|
-
* This method derives child private keys deterministically from the caller’s
|
|
362
|
-
* long-term private key, the counterparty’s public key, and a caller-supplied
|
|
363
|
-
* invoice number using HMAC over an ECDH shared secret (BRC-42 style derivation).
|
|
364
|
-
*
|
|
365
|
-
* This construction does NOT implement a formally authenticated key exchange
|
|
366
|
-
* (AKE) and does NOT provide the following security properties:
|
|
367
|
-
*
|
|
368
|
-
* - Forward secrecy: Compromise of a long-term private key compromises all
|
|
369
|
-
* past and future child keys derived from it.
|
|
370
|
-
* - Replay protection: Child keys are deterministic for a given invoice
|
|
371
|
-
* number and key pair; previously observed messages can be replayed.
|
|
372
|
-
* - Explicit authentication / identity binding: Possession of a public key
|
|
373
|
-
* alone does not guarantee the intended peer identity, enabling potential
|
|
374
|
-
* identity misbinding attacks if higher-level identity verification is absent.
|
|
375
|
-
*
|
|
376
|
-
* This derivation is intended for lightweight, deterministic key hierarchies
|
|
377
|
-
* where both parties already possess and trust each other’s long-term public
|
|
378
|
-
* keys. It SHOULD NOT be used as a drop-in replacement for a standard
|
|
379
|
-
* authenticated key exchange (e.g. X3DH, Noise, or SIGMA) in high-security or
|
|
380
|
-
* high-value contexts.
|
|
381
|
-
*
|
|
382
|
-
* Any future protocol providing forward secrecy, replay protection, or strong
|
|
383
|
-
* peer authentication will require a versioned, breaking change.
|
|
384
|
-
*/
|
|
385
358
|
/**
|
|
386
359
|
* Derives a child key with BRC-42.
|
|
387
360
|
* @param publicKey The public key of the other party
|
|
@@ -598,34 +598,3 @@ describe('AESGCM large input (non-mocked)', () => {
|
|
|
598
598
|
expectUint8ArrayEqual(decryptedBytes, plaintext)
|
|
599
599
|
})
|
|
600
600
|
})
|
|
601
|
-
|
|
602
|
-
describe('multiply reduction edge cases', () => {
|
|
603
|
-
it('applies reduction polynomial when LSB carry is set', () => {
|
|
604
|
-
// Force reduction path by setting v[15] LSB = 1
|
|
605
|
-
const a = new Uint8Array(16)
|
|
606
|
-
a[0] = 0x01
|
|
607
|
-
|
|
608
|
-
const b = new Uint8Array(16)
|
|
609
|
-
b[15] = 0x01
|
|
610
|
-
|
|
611
|
-
const out = multiply(a, b)
|
|
612
|
-
|
|
613
|
-
// We don't assert a magic value — we assert that output is non-zero
|
|
614
|
-
// and stable across runs (reduction happened)
|
|
615
|
-
expect(out.some(v => v !== 0)).toBe(true)
|
|
616
|
-
})
|
|
617
|
-
|
|
618
|
-
it('does not reduce when LSB carry is zero', () => {
|
|
619
|
-
const a = new Uint8Array(16)
|
|
620
|
-
a[0] = 0x01
|
|
621
|
-
|
|
622
|
-
const b = new Uint8Array(16)
|
|
623
|
-
b[15] = 0x00
|
|
624
|
-
|
|
625
|
-
const out = multiply(a, b)
|
|
626
|
-
|
|
627
|
-
expect(out.some(v => v !== 0)).toBe(false)
|
|
628
|
-
})
|
|
629
|
-
})
|
|
630
|
-
|
|
631
|
-
|
|
@@ -323,13 +323,17 @@ describe('verifyNotNull', () => {
|
|
|
323
323
|
})
|
|
324
324
|
})
|
|
325
325
|
|
|
326
|
-
describe('toUTF8
|
|
326
|
+
describe('toUTF8 UTF-8 decoding', () => {
|
|
327
327
|
|
|
328
|
-
it('
|
|
328
|
+
it('decodes ASCII bytes', () => {
|
|
329
|
+
expect(toUTF8([0x48, 0x65, 0x6c, 0x6c, 0x6f])).toBe('Hello')
|
|
330
|
+
})
|
|
331
|
+
|
|
332
|
+
it('replaces invalid 2-byte sequences with U+FFFD and continues decoding', () => {
|
|
329
333
|
// 0xC2 should expect a continuation byte 0x80–0xBF
|
|
330
334
|
const arr = [0xC2, 0x20] // 0x20 is INVALID continuation
|
|
331
335
|
const str = toUTF8(arr)
|
|
332
|
-
expect(str).toBe('\uFFFD')
|
|
336
|
+
expect(str).toBe('\uFFFD ')
|
|
333
337
|
})
|
|
334
338
|
|
|
335
339
|
it('decodes valid 3-byte sequences', () => {
|
|
@@ -337,10 +341,10 @@ describe('toUTF8 strict UTF-8 decoding (TOB-21)', () => {
|
|
|
337
341
|
expect(toUTF8(euro)).toBe('€')
|
|
338
342
|
})
|
|
339
343
|
|
|
340
|
-
it('replaces invalid 3-byte sequences', () => {
|
|
344
|
+
it('replaces invalid 3-byte sequences with U+FFFD and continues decoding', () => {
|
|
341
345
|
// Middle byte invalid
|
|
342
346
|
const arr = [0xE2, 0x20, 0xAC]
|
|
343
|
-
expect(toUTF8(arr)).toBe('\uFFFD')
|
|
347
|
+
expect(toUTF8(arr)).toBe('\uFFFD \uFFFD')
|
|
344
348
|
})
|
|
345
349
|
|
|
346
350
|
it('decodes valid 4-byte sequences into surrogate pairs', () => {
|
|
@@ -348,10 +352,10 @@ describe('toUTF8 strict UTF-8 decoding (TOB-21)', () => {
|
|
|
348
352
|
expect(toUTF8(smile)).toBe('😀')
|
|
349
353
|
})
|
|
350
354
|
|
|
351
|
-
it('replaces invalid 4-byte sequences with U+FFFD', () => {
|
|
355
|
+
it('replaces invalid 4-byte sequences with U+FFFD and continues decoding', () => {
|
|
352
356
|
// 0x9F is valid, 0x20 is INVALID continuation for byte 3
|
|
353
357
|
const arr = [0xF0, 0x9F, 0x20, 0x80]
|
|
354
|
-
expect(toUTF8(arr)).toBe('\uFFFD')
|
|
358
|
+
expect(toUTF8(arr)).toBe('\uFFFD \uFFFD')
|
|
355
359
|
})
|
|
356
360
|
|
|
357
361
|
it('replaces incomplete UTF-8 sequence at end', () => {
|
|
@@ -359,6 +363,25 @@ describe('toUTF8 strict UTF-8 decoding (TOB-21)', () => {
|
|
|
359
363
|
expect(toUTF8(arr)).toBe('\uFFFD')
|
|
360
364
|
})
|
|
361
365
|
|
|
366
|
+
it('replaces overlong sequences with U+FFFD', () => {
|
|
367
|
+
expect(toUTF8([0xC0, 0xAF])).toBe('\uFFFD\uFFFD')
|
|
368
|
+
})
|
|
369
|
+
|
|
370
|
+
it('replaces UTF-8 encoded surrogates with U+FFFD', () => {
|
|
371
|
+
expect(toUTF8([0xED, 0xA0, 0x80])).toBe('\uFFFD\uFFFD\uFFFD')
|
|
372
|
+
})
|
|
373
|
+
|
|
374
|
+
})
|
|
375
|
+
|
|
376
|
+
describe("toArray('utf8') UTF-8 encoding", () => {
|
|
377
|
+
it('round-trips UTF-8 strings', () => {
|
|
378
|
+
const s = 'Hello € 😀'
|
|
379
|
+
expect(toUTF8(toArray(s, 'utf8') as number[])).toBe(s)
|
|
380
|
+
})
|
|
381
|
+
|
|
382
|
+
it('replaces lone surrogates with U+FFFD when encoding', () => {
|
|
383
|
+
expect(toArray('\uD800', 'utf8')).toEqual([0xEF, 0xBF, 0xBD])
|
|
384
|
+
})
|
|
362
385
|
})
|
|
363
386
|
|
|
364
387
|
describe('Point.encode infinity handling', () => {
|
package/src/primitives/utils.ts
CHANGED
|
@@ -168,53 +168,7 @@ export function base64ToArray (msg: string): number[] {
|
|
|
168
168
|
* @returns An array of numbers, each representing a byte in the UTF-8 encoded string.
|
|
169
169
|
*/
|
|
170
170
|
function utf8ToArray (str: string): number[] {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
for (let i = 0; i < str.length; i++) {
|
|
174
|
-
const cp = str.codePointAt(i)
|
|
175
|
-
if (cp === undefined) {
|
|
176
|
-
// Should never be out of range.
|
|
177
|
-
throw new Error(`Index out of range: ${i}`)
|
|
178
|
-
}
|
|
179
|
-
let codePoint = cp
|
|
180
|
-
|
|
181
|
-
if (codePoint > 0xFFFF) {
|
|
182
|
-
// Valid surrogate pair => skip the next code unit because codePointAt
|
|
183
|
-
// has already combined them into a single code point.
|
|
184
|
-
i++
|
|
185
|
-
} else {
|
|
186
|
-
// Check if codePoint is a lone (unpaired) high surrogate or low surrogate.
|
|
187
|
-
if (codePoint >= 0xD800 && codePoint <= 0xDFFF) {
|
|
188
|
-
// Replace with the replacement character (U+FFFD).
|
|
189
|
-
codePoint = 0xFFFD
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// Encode according to the UTF-8 standard
|
|
194
|
-
if (codePoint <= 0x7F) {
|
|
195
|
-
result.push(codePoint)
|
|
196
|
-
} else if (codePoint <= 0x7FF) {
|
|
197
|
-
result.push(
|
|
198
|
-
0xC0 | (codePoint >> 6),
|
|
199
|
-
0x80 | (codePoint & 0x3F)
|
|
200
|
-
)
|
|
201
|
-
} else if (codePoint <= 0xFFFF) {
|
|
202
|
-
result.push(
|
|
203
|
-
0xE0 | (codePoint >> 12),
|
|
204
|
-
0x80 | ((codePoint >> 6) & 0x3F),
|
|
205
|
-
0x80 | (codePoint & 0x3F)
|
|
206
|
-
)
|
|
207
|
-
} else {
|
|
208
|
-
result.push(
|
|
209
|
-
0xF0 | (codePoint >> 18),
|
|
210
|
-
0x80 | ((codePoint >> 12) & 0x3F),
|
|
211
|
-
0x80 | ((codePoint >> 6) & 0x3F),
|
|
212
|
-
0x80 | (codePoint & 0x3F)
|
|
213
|
-
)
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
return result
|
|
171
|
+
return Array.from(new TextEncoder().encode(str))
|
|
218
172
|
}
|
|
219
173
|
|
|
220
174
|
/**
|
|
@@ -223,86 +177,7 @@ function utf8ToArray (str: string): number[] {
|
|
|
223
177
|
* @returns {string} - The UTF-8 encoded string.
|
|
224
178
|
*/
|
|
225
179
|
export const toUTF8 = (arr: number[]): string => {
|
|
226
|
-
|
|
227
|
-
const replacementChar = '\uFFFD'
|
|
228
|
-
for (let i = 0; i < arr.length; i++) {
|
|
229
|
-
const byte1 = arr[i]
|
|
230
|
-
if (byte1 <= 0x7f) {
|
|
231
|
-
result += String.fromCharCode(byte1)
|
|
232
|
-
continue
|
|
233
|
-
}
|
|
234
|
-
const emitReplacement = (): void => {
|
|
235
|
-
result += replacementChar
|
|
236
|
-
}
|
|
237
|
-
if (byte1 >= 0xc0 && byte1 <= 0xdf) {
|
|
238
|
-
if (i + 1 >= arr.length) {
|
|
239
|
-
emitReplacement()
|
|
240
|
-
continue
|
|
241
|
-
}
|
|
242
|
-
const byte2 = arr[i + 1]
|
|
243
|
-
if ((byte2 & 0xc0) !== 0x80) {
|
|
244
|
-
emitReplacement()
|
|
245
|
-
i += 1
|
|
246
|
-
continue
|
|
247
|
-
}
|
|
248
|
-
const codePoint = ((byte1 & 0x1f) << 6) | (byte2 & 0x3f)
|
|
249
|
-
result += String.fromCharCode(codePoint)
|
|
250
|
-
i += 1
|
|
251
|
-
continue
|
|
252
|
-
}
|
|
253
|
-
if (byte1 >= 0xe0 && byte1 <= 0xef) {
|
|
254
|
-
if (i + 2 >= arr.length) {
|
|
255
|
-
emitReplacement()
|
|
256
|
-
continue
|
|
257
|
-
}
|
|
258
|
-
const byte2 = arr[i + 1]
|
|
259
|
-
const byte3 = arr[i + 2]
|
|
260
|
-
if ((byte2 & 0xc0) !== 0x80 || (byte3 & 0xc0) !== 0x80) {
|
|
261
|
-
emitReplacement()
|
|
262
|
-
i += 2
|
|
263
|
-
continue
|
|
264
|
-
}
|
|
265
|
-
const codePoint =
|
|
266
|
-
((byte1 & 0x0f) << 12) |
|
|
267
|
-
((byte2 & 0x3f) << 6) |
|
|
268
|
-
(byte3 & 0x3f)
|
|
269
|
-
|
|
270
|
-
result += String.fromCharCode(codePoint)
|
|
271
|
-
i += 2
|
|
272
|
-
continue
|
|
273
|
-
}
|
|
274
|
-
if (byte1 >= 0xf0 && byte1 <= 0xf7) {
|
|
275
|
-
if (i + 3 >= arr.length) {
|
|
276
|
-
emitReplacement()
|
|
277
|
-
continue
|
|
278
|
-
}
|
|
279
|
-
const byte2 = arr[i + 1]
|
|
280
|
-
const byte3 = arr[i + 2]
|
|
281
|
-
const byte4 = arr[i + 3]
|
|
282
|
-
if (
|
|
283
|
-
(byte2 & 0xc0) !== 0x80 ||
|
|
284
|
-
(byte3 & 0xc0) !== 0x80 ||
|
|
285
|
-
(byte4 & 0xc0) !== 0x80
|
|
286
|
-
) {
|
|
287
|
-
emitReplacement()
|
|
288
|
-
i += 3
|
|
289
|
-
continue
|
|
290
|
-
}
|
|
291
|
-
const codePoint =
|
|
292
|
-
((byte1 & 0x07) << 18) |
|
|
293
|
-
((byte2 & 0x3f) << 12) |
|
|
294
|
-
((byte3 & 0x3f) << 6) |
|
|
295
|
-
(byte4 & 0x3f)
|
|
296
|
-
const offset = codePoint - 0x10000
|
|
297
|
-
const highSurrogate = 0xd800 + (offset >> 10)
|
|
298
|
-
const lowSurrogate = 0xdc00 + (offset & 0x3ff)
|
|
299
|
-
result += String.fromCharCode(highSurrogate, lowSurrogate)
|
|
300
|
-
i += 3
|
|
301
|
-
continue
|
|
302
|
-
}
|
|
303
|
-
emitReplacement()
|
|
304
|
-
}
|
|
305
|
-
return result
|
|
180
|
+
return new TextDecoder().decode(new Uint8Array(arr))
|
|
306
181
|
}
|
|
307
182
|
|
|
308
183
|
/**
|