react-native-ble-mesh 1.0.1
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/CHANGELOG.md +151 -0
- package/LICENSE +21 -0
- package/README.md +706 -0
- package/docs/API.md +462 -0
- package/docs/ARCHITECTURE.md +384 -0
- package/docs/CONTRIBUTING.md +244 -0
- package/docs/NODE_QUICKSTART.md +259 -0
- package/docs/PROTOCOL.md +195 -0
- package/docs/REACT_NATIVE.md +315 -0
- package/docs/SECURITY.md +152 -0
- package/docs/api/constants_audio.js.html +184 -0
- package/docs/api/constants_ble.js.html +165 -0
- package/docs/api/constants_crypto.js.html +107 -0
- package/docs/api/constants_errors.js.html +256 -0
- package/docs/api/constants_events.js.html +148 -0
- package/docs/api/constants_index.js.html +76 -0
- package/docs/api/constants_protocol.js.html +205 -0
- package/docs/api/crypto_aead.js.html +243 -0
- package/docs/api/crypto_chacha20.js.html +235 -0
- package/docs/api/crypto_hkdf.js.html +241 -0
- package/docs/api/crypto_hmac.js.html +197 -0
- package/docs/api/crypto_index.js.html +126 -0
- package/docs/api/crypto_keys_KeyManager.js.html +325 -0
- package/docs/api/crypto_keys_KeyPair.js.html +270 -0
- package/docs/api/crypto_keys_SecureStorage.js.html +273 -0
- package/docs/api/crypto_keys_index.js.html +86 -0
- package/docs/api/crypto_noise_handshake.js.html +464 -0
- package/docs/api/crypto_noise_index.js.html +81 -0
- package/docs/api/crypto_noise_session.js.html +307 -0
- package/docs/api/crypto_noise_state.js.html +322 -0
- package/docs/api/crypto_poly1305.js.html +167 -0
- package/docs/api/crypto_sha256.js.html +294 -0
- package/docs/api/crypto_x25519.js.html +208 -0
- package/docs/api/errors_AudioError.js.html +218 -0
- package/docs/api/errors_ConnectionError.js.html +163 -0
- package/docs/api/errors_CryptoError.js.html +157 -0
- package/docs/api/errors_HandshakeError.js.html +176 -0
- package/docs/api/errors_MeshError.js.html +154 -0
- package/docs/api/errors_MessageError.js.html +183 -0
- package/docs/api/errors_ValidationError.js.html +204 -0
- package/docs/api/errors_index.js.html +78 -0
- package/docs/api/fonts/OpenSans-Bold-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-Bold-webfont.svg +1830 -0
- package/docs/api/fonts/OpenSans-Bold-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-BoldItalic-webfont.svg +1830 -0
- package/docs/api/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-Italic-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-Italic-webfont.svg +1830 -0
- package/docs/api/fonts/OpenSans-Italic-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-Light-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-Light-webfont.svg +1831 -0
- package/docs/api/fonts/OpenSans-Light-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-LightItalic-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-LightItalic-webfont.svg +1835 -0
- package/docs/api/fonts/OpenSans-LightItalic-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-Regular-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-Regular-webfont.svg +1831 -0
- package/docs/api/fonts/OpenSans-Regular-webfont.woff +0 -0
- package/docs/api/hooks_AppStateManager.js.html +233 -0
- package/docs/api/hooks_index.js.html +87 -0
- package/docs/api/hooks_useMesh.js.html +213 -0
- package/docs/api/hooks_useMessages.js.html +263 -0
- package/docs/api/hooks_usePeers.js.html +165 -0
- package/docs/api/index.html +868 -0
- package/docs/api/index.js.html +236 -0
- package/docs/api/mesh_dedup_BloomFilter.js.html +261 -0
- package/docs/api/mesh_dedup_DedupManager.js.html +266 -0
- package/docs/api/mesh_dedup_MessageCache.js.html +273 -0
- package/docs/api/mesh_dedup_index.js.html +70 -0
- package/docs/api/mesh_fragment_Assembler.js.html +335 -0
- package/docs/api/mesh_fragment_Fragmenter.js.html +230 -0
- package/docs/api/mesh_fragment_index.js.html +75 -0
- package/docs/api/mesh_index.js.html +72 -0
- package/docs/api/mesh_peer_Peer.js.html +296 -0
- package/docs/api/mesh_peer_PeerDiscovery.js.html +334 -0
- package/docs/api/mesh_peer_PeerManager.js.html +320 -0
- package/docs/api/mesh_peer_index.js.html +70 -0
- package/docs/api/mesh_router_MessageRouter.js.html +411 -0
- package/docs/api/mesh_router_PathFinder.js.html +386 -0
- package/docs/api/mesh_router_RouteTable.js.html +346 -0
- package/docs/api/mesh_router_index.js.html +70 -0
- package/docs/api/module-audio_buffer.html +168 -0
- package/docs/api/module-audio_buffer_FrameBuffer-FrameBuffer.html +2971 -0
- package/docs/api/module-audio_buffer_FrameBuffer.html +178 -0
- package/docs/api/module-audio_buffer_JitterBuffer-JitterBuffer.html +2761 -0
- package/docs/api/module-audio_buffer_JitterBuffer.html +178 -0
- package/docs/api/module-audio_codec.html +168 -0
- package/docs/api/module-audio_codec_LC3Codec-LC3Codec.html +2876 -0
- package/docs/api/module-audio_codec_LC3Codec.html +178 -0
- package/docs/api/module-audio_codec_LC3Decoder-LC3Decoder.html +1788 -0
- package/docs/api/module-audio_codec_LC3Decoder.html +178 -0
- package/docs/api/module-audio_codec_LC3Encoder-LC3Encoder.html +1512 -0
- package/docs/api/module-audio_codec_LC3Encoder.html +178 -0
- package/docs/api/module-audio_session.html +168 -0
- package/docs/api/module-audio_session_AudioSession-AudioSession.html +3922 -0
- package/docs/api/module-audio_session_AudioSession.html +178 -0
- package/docs/api/module-audio_session_VoiceMessage-VoiceMessage.html +3690 -0
- package/docs/api/module-audio_session_VoiceMessage-VoiceMessageRecorder.html +1780 -0
- package/docs/api/module-audio_session_VoiceMessage.html +332 -0
- package/docs/api/module-audio_transport.html +168 -0
- package/docs/api/module-audio_transport_AudioFragmenter-AudioAssembler.html +1545 -0
- package/docs/api/module-audio_transport_AudioFragmenter-AudioFragmenter.html +658 -0
- package/docs/api/module-audio_transport_AudioFragmenter.html +181 -0
- package/docs/api/module-audio_transport_AudioFramer.html +1414 -0
- package/docs/api/module-constants.html +168 -0
- package/docs/api/module-constants_audio.html +1782 -0
- package/docs/api/module-constants_ble.html +940 -0
- package/docs/api/module-constants_crypto.html +823 -0
- package/docs/api/module-constants_errors.html +316 -0
- package/docs/api/module-constants_events.html +244 -0
- package/docs/api/module-constants_protocol.html +1534 -0
- package/docs/api/module-crypto.html +169 -0
- package/docs/api/module-crypto_aead.html +1625 -0
- package/docs/api/module-crypto_chacha20.html +1440 -0
- package/docs/api/module-crypto_hkdf.html +1421 -0
- package/docs/api/module-crypto_hmac.html +828 -0
- package/docs/api/module-crypto_keys.html +169 -0
- package/docs/api/module-crypto_keys_KeyManager-KeyManager.html +2364 -0
- package/docs/api/module-crypto_keys_KeyManager.html +252 -0
- package/docs/api/module-crypto_keys_KeyPair.html +245 -0
- package/docs/api/module-crypto_keys_SecureStorage-MemorySecureStorage.html +923 -0
- package/docs/api/module-crypto_keys_SecureStorage-SecureStorage.html +942 -0
- package/docs/api/module-crypto_keys_SecureStorage.html +516 -0
- package/docs/api/module-crypto_noise.html +169 -0
- package/docs/api/module-crypto_noise_handshake-NoiseHandshake.html +2240 -0
- package/docs/api/module-crypto_noise_handshake.html +782 -0
- package/docs/api/module-crypto_noise_session-NoiseSession.html +1804 -0
- package/docs/api/module-crypto_noise_session.html +325 -0
- package/docs/api/module-crypto_noise_state-SymmetricState.html +1387 -0
- package/docs/api/module-crypto_noise_state.html +324 -0
- package/docs/api/module-crypto_poly1305.html +884 -0
- package/docs/api/module-crypto_sha256-HashContext.html +447 -0
- package/docs/api/module-crypto_sha256.html +942 -0
- package/docs/api/module-crypto_x25519.html +1503 -0
- package/docs/api/module-errors.html +168 -0
- package/docs/api/module-errors_AudioError-AudioError.html +4711 -0
- package/docs/api/module-errors_AudioError.html +178 -0
- package/docs/api/module-errors_ConnectionError-ConnectionError.html +3649 -0
- package/docs/api/module-errors_ConnectionError.html +178 -0
- package/docs/api/module-errors_CryptoError-CryptoError.html +3453 -0
- package/docs/api/module-errors_CryptoError.html +178 -0
- package/docs/api/module-errors_HandshakeError-HandshakeError.html +4261 -0
- package/docs/api/module-errors_HandshakeError.html +178 -0
- package/docs/api/module-errors_MeshError-MeshError.html +2155 -0
- package/docs/api/module-errors_MeshError.html +178 -0
- package/docs/api/module-errors_MessageError-MessageError.html +4545 -0
- package/docs/api/module-errors_MessageError.html +178 -0
- package/docs/api/module-errors_ValidationError-ValidationError.html +3432 -0
- package/docs/api/module-errors_ValidationError.html +178 -0
- package/docs/api/module-hooks.html +182 -0
- package/docs/api/module-hooks_AppStateManager-AppStateManager.html +1620 -0
- package/docs/api/module-hooks_AppStateManager.html +178 -0
- package/docs/api/module-hooks_useMesh.html +457 -0
- package/docs/api/module-hooks_useMessages.html +466 -0
- package/docs/api/module-hooks_usePeers.html +348 -0
- package/docs/api/module-mesh.html +168 -0
- package/docs/api/module-mesh_dedup.html +168 -0
- package/docs/api/module-mesh_dedup_BloomFilter-BloomFilter.html +2158 -0
- package/docs/api/module-mesh_dedup_BloomFilter.html +178 -0
- package/docs/api/module-mesh_dedup_DedupManager-DedupManager.html +2880 -0
- package/docs/api/module-mesh_dedup_DedupManager.html +178 -0
- package/docs/api/module-mesh_dedup_MessageCache-CacheNode.html +246 -0
- package/docs/api/module-mesh_dedup_MessageCache-MessageCache.html +2314 -0
- package/docs/api/module-mesh_dedup_MessageCache.html +181 -0
- package/docs/api/module-mesh_fragment.html +168 -0
- package/docs/api/module-mesh_fragment_Assembler-Assembler.html +2869 -0
- package/docs/api/module-mesh_fragment_Assembler-PendingFragmentSet.html +895 -0
- package/docs/api/module-mesh_fragment_Assembler.html +181 -0
- package/docs/api/module-mesh_fragment_Fragmenter.html +1084 -0
- package/docs/api/module-mesh_peer.html +168 -0
- package/docs/api/module-mesh_peer_Peer-Peer.html +4986 -0
- package/docs/api/module-mesh_peer_Peer.html +178 -0
- package/docs/api/module-mesh_peer_PeerDiscovery-PeerDiscovery.html +3423 -0
- package/docs/api/module-mesh_peer_PeerDiscovery.html +438 -0
- package/docs/api/module-mesh_peer_PeerManager-PeerManager.html +5258 -0
- package/docs/api/module-mesh_peer_PeerManager.html +178 -0
- package/docs/api/module-mesh_router.html +168 -0
- package/docs/api/module-mesh_router_MessageRouter-MessageRouter.html +3285 -0
- package/docs/api/module-mesh_router_MessageRouter.html +178 -0
- package/docs/api/module-mesh_router_PathFinder-PathFinder.html +3323 -0
- package/docs/api/module-mesh_router_PathFinder.html +421 -0
- package/docs/api/module-mesh_router_RouteTable-RouteTable.html +4115 -0
- package/docs/api/module-mesh_router_RouteTable.html +421 -0
- package/docs/api/module-protocol.html +169 -0
- package/docs/api/module-protocol_crc32.html +815 -0
- package/docs/api/module-protocol_deserializer.html +1393 -0
- package/docs/api/module-protocol_header-MessageHeader.html +2879 -0
- package/docs/api/module-protocol_header.html +892 -0
- package/docs/api/module-protocol_message-Message.html +4682 -0
- package/docs/api/module-protocol_message.html +178 -0
- package/docs/api/module-protocol_serializer.html +911 -0
- package/docs/api/module-protocol_validator.html +1396 -0
- package/docs/api/module-rn-ble-mesh.html +866 -0
- package/docs/api/module-service.html +168 -0
- package/docs/api/module-service_HandshakeManager-HandshakeManager.html +185 -0
- package/docs/api/module-service_HandshakeManager.html +175 -0
- package/docs/api/module-service_MeshService-MeshService.html +185 -0
- package/docs/api/module-service_MeshService.html +175 -0
- package/docs/api/module-service_SessionManager-SessionManager.html +174 -0
- package/docs/api/module-service_SessionManager.html +175 -0
- package/docs/api/module-service_audio.html +168 -0
- package/docs/api/module-service_audio_AudioManager-AudioManager.html +4653 -0
- package/docs/api/module-service_audio_AudioManager.html +254 -0
- package/docs/api/module-service_text.html +168 -0
- package/docs/api/module-service_text_TextManager-TextManager.html +6104 -0
- package/docs/api/module-service_text_TextManager.html +254 -0
- package/docs/api/module-service_text_broadcast.html +168 -0
- package/docs/api/module-service_text_broadcast_BroadcastManager-BroadcastManager.html +2434 -0
- package/docs/api/module-service_text_broadcast_BroadcastManager.html +254 -0
- package/docs/api/module-service_text_channel.html +168 -0
- package/docs/api/module-service_text_channel_Channel-Channel.html +4337 -0
- package/docs/api/module-service_text_channel_Channel.html +178 -0
- package/docs/api/module-service_text_channel_ChannelManager-ChannelManager.html +1927 -0
- package/docs/api/module-service_text_channel_ChannelManager.html +175 -0
- package/docs/api/module-service_text_message.html +168 -0
- package/docs/api/module-service_text_message_TextMessage-TextMessage.html +4162 -0
- package/docs/api/module-service_text_message_TextMessage.html +178 -0
- package/docs/api/module-service_text_message_TextSerializer.html +1725 -0
- package/docs/api/module-storage.html +168 -0
- package/docs/api/module-storage_AsyncStorageAdapter-AsyncStorageAdapter.html +4159 -0
- package/docs/api/module-storage_AsyncStorageAdapter.html +178 -0
- package/docs/api/module-storage_MemoryStorage-MemoryStorage.html +3154 -0
- package/docs/api/module-storage_MemoryStorage.html +178 -0
- package/docs/api/module-storage_MessageStore-MessageStore.html +5299 -0
- package/docs/api/module-storage_MessageStore.html +178 -0
- package/docs/api/module-storage_Storage-Storage.html +4169 -0
- package/docs/api/module-storage_Storage.html +178 -0
- package/docs/api/module-transport.html +168 -0
- package/docs/api/module-transport_BLEAdapter-BLEAdapter.html +4724 -0
- package/docs/api/module-transport_BLEAdapter.html +178 -0
- package/docs/api/module-transport_BLETransport-BLETransport.html +3263 -0
- package/docs/api/module-transport_BLETransport.html +178 -0
- package/docs/api/module-transport_MockTransport-MockTransport.html +3947 -0
- package/docs/api/module-transport_MockTransport.html +178 -0
- package/docs/api/module-transport_NodeBLEAdapter-NodeBLEAdapter.html +3216 -0
- package/docs/api/module-transport_NodeBLEAdapter.html +178 -0
- package/docs/api/module-transport_RNBLEAdapter-RNBLEAdapter.html +3216 -0
- package/docs/api/module-transport_RNBLEAdapter.html +178 -0
- package/docs/api/module-transport_Transport-Transport.html +4071 -0
- package/docs/api/module-transport_Transport.html +254 -0
- package/docs/api/module-transport_adapters.html +168 -0
- package/docs/api/module-transport_adapters_BLEAdapter-BLEAdapter.html +4724 -0
- package/docs/api/module-transport_adapters_BLEAdapter.html +178 -0
- package/docs/api/module-transport_adapters_NodeBLEAdapter-NodeBLEAdapter.html +3216 -0
- package/docs/api/module-transport_adapters_NodeBLEAdapter.html +178 -0
- package/docs/api/module-transport_adapters_RNBLEAdapter-RNBLEAdapter.html +3216 -0
- package/docs/api/module-transport_adapters_RNBLEAdapter.html +178 -0
- package/docs/api/module-utils.html +168 -0
- package/docs/api/module-utils_BoundedMap-BoundedMap.html +3301 -0
- package/docs/api/module-utils_BoundedMap.html +178 -0
- package/docs/api/module-utils_EventEmitter-EventEmitter.html +3358 -0
- package/docs/api/module-utils_EventEmitter.html +178 -0
- package/docs/api/module-utils_LRUCache-LRUCache.html +4134 -0
- package/docs/api/module-utils_LRUCache.html +178 -0
- package/docs/api/module-utils_RateLimiter-RateLimiter.html +2176 -0
- package/docs/api/module-utils_RateLimiter.html +500 -0
- package/docs/api/module-utils_TimeoutManager-TimeoutManager.html +1781 -0
- package/docs/api/module-utils_TimeoutManager.html +175 -0
- package/docs/api/module-utils_bytes.html +1789 -0
- package/docs/api/module-utils_debug.html +837 -0
- package/docs/api/module-utils_encoding.html +1184 -0
- package/docs/api/module-utils_retry.html +1457 -0
- package/docs/api/module-utils_time.html +1665 -0
- package/docs/api/module-utils_uuid.html +1269 -0
- package/docs/api/module-utils_validation.html +2176 -0
- package/docs/api/protocol_crc32.js.html +147 -0
- package/docs/api/protocol_deserializer.js.html +295 -0
- package/docs/api/protocol_header.js.html +276 -0
- package/docs/api/protocol_index.js.html +120 -0
- package/docs/api/protocol_message.js.html +287 -0
- package/docs/api/protocol_serializer.js.html +240 -0
- package/docs/api/protocol_validator.js.html +330 -0
- package/docs/api/scripts/linenumber.js +25 -0
- package/docs/api/scripts/prettify/Apache-License-2.0.txt +202 -0
- package/docs/api/scripts/prettify/lang-css.js +2 -0
- package/docs/api/scripts/prettify/prettify.js +28 -0
- package/docs/api/service_HandshakeManager.js.html +232 -0
- package/docs/api/service_MeshService.js.html +371 -0
- package/docs/api/service_SessionManager.js.html +153 -0
- package/docs/api/service_audio_AudioManager.js.html +541 -0
- package/docs/api/service_audio_buffer_FrameBuffer.js.html +223 -0
- package/docs/api/service_audio_buffer_JitterBuffer.js.html +244 -0
- package/docs/api/service_audio_buffer_index.js.html +68 -0
- package/docs/api/service_audio_codec_LC3Codec.js.html +345 -0
- package/docs/api/service_audio_codec_LC3Decoder.js.html +185 -0
- package/docs/api/service_audio_codec_LC3Encoder.js.html +194 -0
- package/docs/api/service_audio_codec_index.js.html +70 -0
- package/docs/api/service_audio_index.js.html +96 -0
- package/docs/api/service_audio_session_AudioSession.js.html +348 -0
- package/docs/api/service_audio_session_VoiceMessage.js.html +432 -0
- package/docs/api/service_audio_session_index.js.html +70 -0
- package/docs/api/service_audio_transport_AudioFragmenter.js.html +314 -0
- package/docs/api/service_audio_transport_AudioFramer.js.html +236 -0
- package/docs/api/service_audio_transport_index.js.html +69 -0
- package/docs/api/service_index.js.html +93 -0
- package/docs/api/service_text_TextManager.js.html +578 -0
- package/docs/api/service_text_broadcast_BroadcastManager.js.html +276 -0
- package/docs/api/service_text_broadcast_index.js.html +66 -0
- package/docs/api/service_text_channel_Channel.js.html +280 -0
- package/docs/api/service_text_channel_ChannelManager.js.html +225 -0
- package/docs/api/service_text_channel_index.js.html +68 -0
- package/docs/api/service_text_index.js.html +85 -0
- package/docs/api/service_text_message_TextMessage.js.html +350 -0
- package/docs/api/service_text_message_TextSerializer.js.html +218 -0
- package/docs/api/service_text_message_index.js.html +68 -0
- package/docs/api/storage_AsyncStorageAdapter.js.html +357 -0
- package/docs/api/storage_MemoryStorage.js.html +279 -0
- package/docs/api/storage_MessageStore.js.html +369 -0
- package/docs/api/storage_Storage.js.html +214 -0
- package/docs/api/storage_index.js.html +72 -0
- package/docs/api/styles/jsdoc-default.css +358 -0
- package/docs/api/styles/prettify-jsdoc.css +111 -0
- package/docs/api/styles/prettify-tomorrow.css +132 -0
- package/docs/api/transport_BLEAdapter.js.html +231 -0
- package/docs/api/transport_BLETransport.js.html +411 -0
- package/docs/api/transport_MockTransport.js.html +339 -0
- package/docs/api/transport_NodeBLEAdapter.js.html +479 -0
- package/docs/api/transport_RNBLEAdapter.js.html +382 -0
- package/docs/api/transport_Transport.js.html +242 -0
- package/docs/api/transport_adapters_BLEAdapter.js.html +231 -0
- package/docs/api/transport_adapters_NodeBLEAdapter.js.html +479 -0
- package/docs/api/transport_adapters_RNBLEAdapter.js.html +382 -0
- package/docs/api/transport_adapters_index.js.html +70 -0
- package/docs/api/transport_index.js.html +87 -0
- package/docs/api/utils_BoundedMap.js.html +205 -0
- package/docs/api/utils_EventEmitter.js.html +259 -0
- package/docs/api/utils_LRUCache.js.html +256 -0
- package/docs/api/utils_RateLimiter.js.html +256 -0
- package/docs/api/utils_TimeoutManager.js.html +218 -0
- package/docs/api/utils_base64%0A%0AThis%20implementation%20avoids%20string%20concatenation%20in%20loops%20which%20is%20O(n%C2%B2).%0AUses%20array%20building%20which%20is%20O(n)%20-%20critical%20for%20React%20Native%20performance.module_.html +717 -0
- package/docs/api/utils_base64.js.html +205 -0
- package/docs/api/utils_bytes.js.html +241 -0
- package/docs/api/utils_debug.js.html +205 -0
- package/docs/api/utils_encoding.js.html +302 -0
- package/docs/api/utils_index.js.html +160 -0
- package/docs/api/utils_retry.js.html +200 -0
- package/docs/api/utils_time.js.html +220 -0
- package/docs/api/utils_uuid.js.html +199 -0
- package/docs/api/utils_validation.js.html +259 -0
- package/examples/node-chat/chat.js +220 -0
- package/examples/node-quickstart/index.js +94 -0
- package/examples/testing/test-helper.js +182 -0
- package/package.json +111 -0
- package/src/constants/audio.js +130 -0
- package/src/constants/ble.js +111 -0
- package/src/constants/crypto.js +53 -0
- package/src/constants/errors.js +202 -0
- package/src/constants/events.js +94 -0
- package/src/constants/index.js +22 -0
- package/src/constants/protocol.js +151 -0
- package/src/crypto/aead.js +189 -0
- package/src/crypto/chacha20.js +181 -0
- package/src/crypto/hkdf.js +187 -0
- package/src/crypto/hmac.js +143 -0
- package/src/crypto/index.js +72 -0
- package/src/crypto/keys/KeyManager.js +271 -0
- package/src/crypto/keys/KeyPair.js +216 -0
- package/src/crypto/keys/SecureStorage.js +219 -0
- package/src/crypto/keys/index.js +32 -0
- package/src/crypto/noise/handshake.js +410 -0
- package/src/crypto/noise/index.js +27 -0
- package/src/crypto/noise/session.js +253 -0
- package/src/crypto/noise/state.js +268 -0
- package/src/crypto/poly1305.js +113 -0
- package/src/crypto/sha256.js +240 -0
- package/src/crypto/x25519.js +154 -0
- package/src/errors/AudioError.js +164 -0
- package/src/errors/ConnectionError.js +109 -0
- package/src/errors/CryptoError.js +103 -0
- package/src/errors/HandshakeError.js +122 -0
- package/src/errors/MeshError.js +100 -0
- package/src/errors/MessageError.js +129 -0
- package/src/errors/ValidationError.js +150 -0
- package/src/errors/index.js +24 -0
- package/src/hooks/AppStateManager.js +179 -0
- package/src/hooks/index.js +33 -0
- package/src/hooks/useMesh.js +159 -0
- package/src/hooks/useMessages.js +209 -0
- package/src/hooks/usePeers.js +111 -0
- package/src/index.d.ts +494 -0
- package/src/index.js +182 -0
- package/src/index.mjs +62 -0
- package/src/mesh/dedup/BloomFilter.js +207 -0
- package/src/mesh/dedup/DedupManager.js +212 -0
- package/src/mesh/dedup/MessageCache.js +219 -0
- package/src/mesh/dedup/index.js +16 -0
- package/src/mesh/fragment/Assembler.js +281 -0
- package/src/mesh/fragment/Fragmenter.js +176 -0
- package/src/mesh/fragment/index.js +21 -0
- package/src/mesh/index.js +18 -0
- package/src/mesh/peer/Peer.js +242 -0
- package/src/mesh/peer/PeerDiscovery.js +280 -0
- package/src/mesh/peer/PeerManager.js +266 -0
- package/src/mesh/peer/index.js +16 -0
- package/src/mesh/router/MessageRouter.js +357 -0
- package/src/mesh/router/PathFinder.js +332 -0
- package/src/mesh/router/RouteTable.js +292 -0
- package/src/mesh/router/index.js +16 -0
- package/src/protocol/crc32.js +93 -0
- package/src/protocol/deserializer.js +241 -0
- package/src/protocol/header.js +222 -0
- package/src/protocol/index.js +66 -0
- package/src/protocol/message.js +233 -0
- package/src/protocol/serializer.js +186 -0
- package/src/protocol/validator.js +276 -0
- package/src/service/HandshakeManager.js +178 -0
- package/src/service/MeshService.js +317 -0
- package/src/service/SessionManager.js +99 -0
- package/src/service/audio/AudioManager.js +487 -0
- package/src/service/audio/buffer/FrameBuffer.js +169 -0
- package/src/service/audio/buffer/JitterBuffer.js +190 -0
- package/src/service/audio/buffer/index.js +14 -0
- package/src/service/audio/codec/LC3Codec.js +291 -0
- package/src/service/audio/codec/LC3Decoder.js +131 -0
- package/src/service/audio/codec/LC3Encoder.js +140 -0
- package/src/service/audio/codec/index.js +16 -0
- package/src/service/audio/index.js +42 -0
- package/src/service/audio/session/AudioSession.js +294 -0
- package/src/service/audio/session/VoiceMessage.js +378 -0
- package/src/service/audio/session/index.js +16 -0
- package/src/service/audio/transport/AudioFragmenter.js +260 -0
- package/src/service/audio/transport/AudioFramer.js +182 -0
- package/src/service/audio/transport/index.js +15 -0
- package/src/service/index.js +39 -0
- package/src/service/text/TextManager.js +524 -0
- package/src/service/text/broadcast/BroadcastManager.js +222 -0
- package/src/service/text/broadcast/index.js +12 -0
- package/src/service/text/channel/Channel.js +226 -0
- package/src/service/text/channel/ChannelManager.js +171 -0
- package/src/service/text/channel/index.js +14 -0
- package/src/service/text/index.js +31 -0
- package/src/service/text/message/TextMessage.js +296 -0
- package/src/service/text/message/TextSerializer.js +164 -0
- package/src/service/text/message/index.js +14 -0
- package/src/storage/AsyncStorageAdapter.js +303 -0
- package/src/storage/MemoryStorage.js +225 -0
- package/src/storage/MessageStore.js +315 -0
- package/src/storage/Storage.js +160 -0
- package/src/storage/index.js +18 -0
- package/src/transport/BLEAdapter.js +177 -0
- package/src/transport/BLETransport.js +357 -0
- package/src/transport/MockTransport.js +285 -0
- package/src/transport/NodeBLEAdapter.js +425 -0
- package/src/transport/RNBLEAdapter.js +328 -0
- package/src/transport/Transport.js +188 -0
- package/src/transport/adapters/BLEAdapter.js +177 -0
- package/src/transport/adapters/NodeBLEAdapter.js +425 -0
- package/src/transport/adapters/RNBLEAdapter.js +328 -0
- package/src/transport/adapters/index.js +16 -0
- package/src/transport/index.js +33 -0
- package/src/utils/BoundedMap.js +151 -0
- package/src/utils/EventEmitter.js +205 -0
- package/src/utils/LRUCache.js +202 -0
- package/src/utils/RateLimiter.js +202 -0
- package/src/utils/TimeoutManager.js +164 -0
- package/src/utils/base64.js +151 -0
- package/src/utils/bytes.js +187 -0
- package/src/utils/debug.js +151 -0
- package/src/utils/encoding.js +248 -0
- package/src/utils/index.js +106 -0
- package/src/utils/retry.js +146 -0
- package/src/utils/time.js +166 -0
- package/src/utils/uuid.js +145 -0
- package/src/utils/validation.js +205 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview ChaCha20 stream cipher implementation (RFC 8439)
|
|
3
|
+
* @module crypto/chacha20
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* ChaCha20 constants: "expand 32-byte k" in ASCII
|
|
10
|
+
* @constant {Uint32Array}
|
|
11
|
+
*/
|
|
12
|
+
const CONSTANTS = new Uint32Array([0x61707865, 0x3320646e, 0x79622d32, 0x6b206574]);
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Performs left rotation on a 32-bit unsigned integer
|
|
16
|
+
* @param {number} v - Value to rotate
|
|
17
|
+
* @param {number} c - Number of bits to rotate
|
|
18
|
+
* @returns {number} Rotated value
|
|
19
|
+
*/
|
|
20
|
+
function rotl32(v, c) {
|
|
21
|
+
return ((v << c) | (v >>> (32 - c))) >>> 0;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* ChaCha20 quarter round operation
|
|
26
|
+
* Modifies state array in place
|
|
27
|
+
* @param {Uint32Array} state - 16-element state array
|
|
28
|
+
* @param {number} a - Index a
|
|
29
|
+
* @param {number} b - Index b
|
|
30
|
+
* @param {number} c - Index c
|
|
31
|
+
* @param {number} d - Index d
|
|
32
|
+
*/
|
|
33
|
+
function quarterRound(state, a, b, c, d) {
|
|
34
|
+
state[a] = (state[a] + state[b]) >>> 0;
|
|
35
|
+
state[d] = rotl32(state[d] ^ state[a], 16);
|
|
36
|
+
|
|
37
|
+
state[c] = (state[c] + state[d]) >>> 0;
|
|
38
|
+
state[b] = rotl32(state[b] ^ state[c], 12);
|
|
39
|
+
|
|
40
|
+
state[a] = (state[a] + state[b]) >>> 0;
|
|
41
|
+
state[d] = rotl32(state[d] ^ state[a], 8);
|
|
42
|
+
|
|
43
|
+
state[c] = (state[c] + state[d]) >>> 0;
|
|
44
|
+
state[b] = rotl32(state[b] ^ state[c], 7);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Creates initial ChaCha20 state from key, counter, and nonce
|
|
49
|
+
* @param {Uint8Array} key - 32-byte key
|
|
50
|
+
* @param {number} counter - 32-bit block counter
|
|
51
|
+
* @param {Uint8Array} nonce - 12-byte nonce
|
|
52
|
+
* @returns {Uint32Array} Initial state (16 x 32-bit words)
|
|
53
|
+
*/
|
|
54
|
+
function createState(key, counter, nonce) {
|
|
55
|
+
const state = new Uint32Array(16);
|
|
56
|
+
const keyView = new DataView(key.buffer, key.byteOffset, key.byteLength);
|
|
57
|
+
const nonceView = new DataView(nonce.buffer, nonce.byteOffset, nonce.byteLength);
|
|
58
|
+
|
|
59
|
+
// Constants
|
|
60
|
+
state[0] = CONSTANTS[0];
|
|
61
|
+
state[1] = CONSTANTS[1];
|
|
62
|
+
state[2] = CONSTANTS[2];
|
|
63
|
+
state[3] = CONSTANTS[3];
|
|
64
|
+
|
|
65
|
+
// Key (little-endian)
|
|
66
|
+
for (let i = 0; i < 8; i++) {
|
|
67
|
+
state[4 + i] = keyView.getUint32(i * 4, true);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Counter
|
|
71
|
+
state[12] = counter >>> 0;
|
|
72
|
+
|
|
73
|
+
// Nonce (little-endian)
|
|
74
|
+
for (let i = 0; i < 3; i++) {
|
|
75
|
+
state[13 + i] = nonceView.getUint32(i * 4, true);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return state;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Computes a single ChaCha20 block
|
|
83
|
+
* @param {Uint32Array} state - 16-element initial state
|
|
84
|
+
* @returns {Uint32Array} 16-element output state
|
|
85
|
+
*/
|
|
86
|
+
function chacha20Block(state) {
|
|
87
|
+
if (!(state instanceof Uint32Array) || state.length !== 16) {
|
|
88
|
+
throw new Error('State must be a 16-element Uint32Array');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const working = new Uint32Array(state);
|
|
92
|
+
|
|
93
|
+
// 20 rounds = 10 double rounds
|
|
94
|
+
for (let i = 0; i < 10; i++) {
|
|
95
|
+
// Column rounds
|
|
96
|
+
quarterRound(working, 0, 4, 8, 12);
|
|
97
|
+
quarterRound(working, 1, 5, 9, 13);
|
|
98
|
+
quarterRound(working, 2, 6, 10, 14);
|
|
99
|
+
quarterRound(working, 3, 7, 11, 15);
|
|
100
|
+
// Diagonal rounds
|
|
101
|
+
quarterRound(working, 0, 5, 10, 15);
|
|
102
|
+
quarterRound(working, 1, 6, 11, 12);
|
|
103
|
+
quarterRound(working, 2, 7, 8, 13);
|
|
104
|
+
quarterRound(working, 3, 4, 9, 14);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Add original state to working state
|
|
108
|
+
const output = new Uint32Array(16);
|
|
109
|
+
for (let i = 0; i < 16; i++) {
|
|
110
|
+
output[i] = (working[i] + state[i]) >>> 0;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return output;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Serializes 32-bit words to bytes (little-endian)
|
|
118
|
+
* @param {Uint32Array} words - Array of 32-bit words
|
|
119
|
+
* @returns {Uint8Array} Byte array
|
|
120
|
+
*/
|
|
121
|
+
function wordsToBytes(words) {
|
|
122
|
+
const bytes = new Uint8Array(words.length * 4);
|
|
123
|
+
const view = new DataView(bytes.buffer);
|
|
124
|
+
for (let i = 0; i < words.length; i++) {
|
|
125
|
+
view.setUint32(i * 4, words[i], true);
|
|
126
|
+
}
|
|
127
|
+
return bytes;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* ChaCha20 encryption/decryption (XOR with keystream)
|
|
132
|
+
* @param {Uint8Array} key - 32-byte key
|
|
133
|
+
* @param {Uint8Array} nonce - 12-byte nonce
|
|
134
|
+
* @param {number} counter - Initial block counter
|
|
135
|
+
* @param {Uint8Array} data - Data to encrypt/decrypt
|
|
136
|
+
* @returns {Uint8Array} Encrypted/decrypted data
|
|
137
|
+
* @throws {Error} If key is not 32 bytes or nonce is not 12 bytes
|
|
138
|
+
*/
|
|
139
|
+
function chacha20(key, nonce, counter, data) {
|
|
140
|
+
if (!(key instanceof Uint8Array) || key.length !== 32) {
|
|
141
|
+
throw new Error('Key must be 32 bytes');
|
|
142
|
+
}
|
|
143
|
+
if (!(nonce instanceof Uint8Array) || nonce.length !== 12) {
|
|
144
|
+
throw new Error('Nonce must be 12 bytes');
|
|
145
|
+
}
|
|
146
|
+
if (!(data instanceof Uint8Array)) {
|
|
147
|
+
throw new Error('Data must be a Uint8Array');
|
|
148
|
+
}
|
|
149
|
+
if (typeof counter !== 'number' || counter < 0 || counter > 0xFFFFFFFF) {
|
|
150
|
+
throw new Error('Counter must be a 32-bit unsigned integer');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const output = new Uint8Array(data.length);
|
|
154
|
+
let offset = 0;
|
|
155
|
+
let blockCounter = counter;
|
|
156
|
+
|
|
157
|
+
while (offset < data.length) {
|
|
158
|
+
const state = createState(key, blockCounter, nonce);
|
|
159
|
+
const keystream = wordsToBytes(chacha20Block(state));
|
|
160
|
+
const remaining = data.length - offset;
|
|
161
|
+
const blockSize = Math.min(64, remaining);
|
|
162
|
+
|
|
163
|
+
for (let i = 0; i < blockSize; i++) {
|
|
164
|
+
output[offset + i] = data[offset + i] ^ keystream[i];
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
offset += blockSize;
|
|
168
|
+
blockCounter = (blockCounter + 1) >>> 0;
|
|
169
|
+
|
|
170
|
+
if (blockCounter === 0 && offset < data.length) {
|
|
171
|
+
throw new Error('Counter overflow');
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return output;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
module.exports = {
|
|
179
|
+
chacha20Block,
|
|
180
|
+
chacha20
|
|
181
|
+
};
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* HKDF Key Derivation Function (RFC 5869)
|
|
5
|
+
* Pure JavaScript implementation using HMAC-SHA256
|
|
6
|
+
* @module crypto/hkdf
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const { hmacSha256 } = require('./hmac');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Hash output length in bytes (SHA-256 = 32 bytes)
|
|
13
|
+
* @constant {number}
|
|
14
|
+
*/
|
|
15
|
+
const HASH_LENGTH = 32;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Maximum output length (255 * hash length)
|
|
19
|
+
* @constant {number}
|
|
20
|
+
*/
|
|
21
|
+
const MAX_OUTPUT_LENGTH = 255 * HASH_LENGTH;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Default salt (32 zero bytes for SHA-256)
|
|
25
|
+
* @constant {Uint8Array}
|
|
26
|
+
*/
|
|
27
|
+
const DEFAULT_SALT = new Uint8Array(HASH_LENGTH);
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* HKDF-Extract: Extract a pseudorandom key from input keying material
|
|
31
|
+
*
|
|
32
|
+
* PRK = HMAC-Hash(salt, IKM)
|
|
33
|
+
*
|
|
34
|
+
* @param {Uint8Array|null} salt - Optional salt value (non-secret random value)
|
|
35
|
+
* If null/undefined/empty, uses zeros
|
|
36
|
+
* @param {Uint8Array} ikm - Input keying material
|
|
37
|
+
* @returns {Uint8Array} Pseudorandom key (32 bytes)
|
|
38
|
+
* @throws {TypeError} If ikm is not a Uint8Array
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* const ikm = new Uint8Array([...sharedSecret]);
|
|
42
|
+
* const salt = crypto.getRandomValues(new Uint8Array(32));
|
|
43
|
+
* const prk = extract(salt, ikm);
|
|
44
|
+
*/
|
|
45
|
+
function extract(salt, ikm) {
|
|
46
|
+
if (!(ikm instanceof Uint8Array)) {
|
|
47
|
+
throw new TypeError('IKM must be a Uint8Array');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Use default salt if not provided or empty
|
|
51
|
+
const actualSalt = (salt && salt.length > 0) ? salt : DEFAULT_SALT;
|
|
52
|
+
|
|
53
|
+
return hmacSha256(actualSalt, ikm);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* HKDF-Expand: Expand a pseudorandom key to desired length
|
|
58
|
+
*
|
|
59
|
+
* T(0) = empty string
|
|
60
|
+
* T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
|
|
61
|
+
* T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
|
|
62
|
+
* ...
|
|
63
|
+
* OKM = first L bytes of T(1) | T(2) | ...
|
|
64
|
+
*
|
|
65
|
+
* @param {Uint8Array} prk - Pseudorandom key (from extract)
|
|
66
|
+
* @param {Uint8Array} info - Context and application specific info
|
|
67
|
+
* @param {number} length - Desired output length in bytes (max 8160)
|
|
68
|
+
* @returns {Uint8Array} Output keying material of specified length
|
|
69
|
+
* @throws {TypeError} If prk or info is not a Uint8Array
|
|
70
|
+
* @throws {RangeError} If length exceeds maximum (255 * 32 = 8160 bytes)
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* const prk = extract(salt, ikm);
|
|
74
|
+
* const info = new TextEncoder().encode('encryption-key');
|
|
75
|
+
* const key = expand(prk, info, 32);
|
|
76
|
+
*/
|
|
77
|
+
function expand(prk, info, length) {
|
|
78
|
+
if (!(prk instanceof Uint8Array)) {
|
|
79
|
+
throw new TypeError('PRK must be a Uint8Array');
|
|
80
|
+
}
|
|
81
|
+
if (!(info instanceof Uint8Array)) {
|
|
82
|
+
throw new TypeError('Info must be a Uint8Array');
|
|
83
|
+
}
|
|
84
|
+
if (!Number.isInteger(length) || length < 0) {
|
|
85
|
+
throw new TypeError('Length must be a non-negative integer');
|
|
86
|
+
}
|
|
87
|
+
if (length > MAX_OUTPUT_LENGTH) {
|
|
88
|
+
throw new RangeError(`Length must not exceed ${MAX_OUTPUT_LENGTH} bytes`);
|
|
89
|
+
}
|
|
90
|
+
if (length === 0) {
|
|
91
|
+
return new Uint8Array(0);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Calculate number of iterations needed
|
|
95
|
+
const n = Math.ceil(length / HASH_LENGTH);
|
|
96
|
+
const okm = new Uint8Array(n * HASH_LENGTH);
|
|
97
|
+
|
|
98
|
+
// T(0) = empty, T(i) = HMAC(PRK, T(i-1) | info | i)
|
|
99
|
+
let previous = new Uint8Array(0);
|
|
100
|
+
|
|
101
|
+
for (let i = 1; i <= n; i++) {
|
|
102
|
+
// Construct input: T(i-1) | info | counter
|
|
103
|
+
const inputLength = previous.length + info.length + 1;
|
|
104
|
+
const input = new Uint8Array(inputLength);
|
|
105
|
+
|
|
106
|
+
let offset = 0;
|
|
107
|
+
if (previous.length > 0) {
|
|
108
|
+
input.set(previous, offset);
|
|
109
|
+
offset += previous.length;
|
|
110
|
+
}
|
|
111
|
+
input.set(info, offset);
|
|
112
|
+
offset += info.length;
|
|
113
|
+
input[offset] = i; // Counter byte (1-indexed)
|
|
114
|
+
|
|
115
|
+
// T(i) = HMAC-Hash(PRK, input)
|
|
116
|
+
previous = hmacSha256(prk, input);
|
|
117
|
+
|
|
118
|
+
// Copy to output
|
|
119
|
+
okm.set(previous, (i - 1) * HASH_LENGTH);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Return only the requested number of bytes
|
|
123
|
+
return okm.subarray(0, length);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* HKDF: Combined extract-then-expand operation
|
|
128
|
+
*
|
|
129
|
+
* Convenience function that performs both HKDF-Extract and HKDF-Expand
|
|
130
|
+
*
|
|
131
|
+
* @param {Uint8Array} ikm - Input keying material
|
|
132
|
+
* @param {Uint8Array|null} salt - Optional salt (uses zeros if null/empty)
|
|
133
|
+
* @param {Uint8Array} info - Context and application specific info
|
|
134
|
+
* @param {number} length - Desired output length in bytes
|
|
135
|
+
* @returns {Uint8Array} Derived key material of specified length
|
|
136
|
+
* @throws {TypeError} If ikm or info is not a Uint8Array
|
|
137
|
+
* @throws {RangeError} If length exceeds maximum
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* const sharedSecret = performDH(myPrivate, theirPublic);
|
|
141
|
+
* const info = new TextEncoder().encode('noise-handshake-v1');
|
|
142
|
+
* const key = derive(sharedSecret, null, info, 32);
|
|
143
|
+
*/
|
|
144
|
+
function derive(ikm, salt, info, length) {
|
|
145
|
+
const prk = extract(salt, ikm);
|
|
146
|
+
return expand(prk, info, length);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Derive multiple keys in one operation
|
|
151
|
+
* Useful for deriving encryption and MAC keys together
|
|
152
|
+
*
|
|
153
|
+
* @param {Uint8Array} ikm - Input keying material
|
|
154
|
+
* @param {Uint8Array|null} salt - Optional salt
|
|
155
|
+
* @param {Uint8Array} info - Context info
|
|
156
|
+
* @param {number[]} lengths - Array of key lengths to derive
|
|
157
|
+
* @returns {Uint8Array[]} Array of derived keys
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* const [encKey, macKey] = deriveMultiple(secret, salt, info, [32, 32]);
|
|
161
|
+
*/
|
|
162
|
+
function deriveMultiple(ikm, salt, info, lengths) {
|
|
163
|
+
if (!Array.isArray(lengths) || lengths.length === 0) {
|
|
164
|
+
throw new TypeError('Lengths must be a non-empty array');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const totalLength = lengths.reduce((sum, len) => sum + len, 0);
|
|
168
|
+
const combined = derive(ikm, salt, info, totalLength);
|
|
169
|
+
|
|
170
|
+
const keys = [];
|
|
171
|
+
let offset = 0;
|
|
172
|
+
for (const len of lengths) {
|
|
173
|
+
keys.push(combined.slice(offset, offset + len));
|
|
174
|
+
offset += len;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return keys;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
module.exports = {
|
|
181
|
+
extract,
|
|
182
|
+
expand,
|
|
183
|
+
derive,
|
|
184
|
+
deriveMultiple,
|
|
185
|
+
HASH_LENGTH,
|
|
186
|
+
MAX_OUTPUT_LENGTH
|
|
187
|
+
};
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* HMAC-SHA256 Implementation (RFC 2104)
|
|
5
|
+
* Pure JavaScript implementation for BLE Mesh Network
|
|
6
|
+
* @module crypto/hmac
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const { hash } = require('./sha256');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* HMAC block size in bytes (SHA-256 uses 64-byte blocks)
|
|
13
|
+
* @constant {number}
|
|
14
|
+
*/
|
|
15
|
+
const BLOCK_SIZE = 64;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Inner padding byte value
|
|
19
|
+
* @constant {number}
|
|
20
|
+
*/
|
|
21
|
+
const IPAD = 0x36;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Outer padding byte value
|
|
25
|
+
* @constant {number}
|
|
26
|
+
*/
|
|
27
|
+
const OPAD = 0x5c;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Compute HMAC-SHA256 of data with given key
|
|
31
|
+
*
|
|
32
|
+
* HMAC is computed as:
|
|
33
|
+
* HMAC(K, m) = H((K' XOR opad) || H((K' XOR ipad) || m))
|
|
34
|
+
*
|
|
35
|
+
* Where K' is the key padded/hashed to block size
|
|
36
|
+
*
|
|
37
|
+
* @param {Uint8Array} key - Secret key (any length)
|
|
38
|
+
* @param {Uint8Array} data - Message to authenticate
|
|
39
|
+
* @returns {Uint8Array} 32-byte HMAC digest
|
|
40
|
+
* @throws {TypeError} If key or data is not a Uint8Array
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* const key = new Uint8Array([0x0b, 0x0b, ...]);
|
|
44
|
+
* const data = new TextEncoder().encode('Hi There');
|
|
45
|
+
* const mac = hmacSha256(key, data);
|
|
46
|
+
*/
|
|
47
|
+
function hmacSha256(key, data) {
|
|
48
|
+
if (!(key instanceof Uint8Array)) {
|
|
49
|
+
throw new TypeError('Key must be a Uint8Array');
|
|
50
|
+
}
|
|
51
|
+
if (!(data instanceof Uint8Array)) {
|
|
52
|
+
throw new TypeError('Data must be a Uint8Array');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Step 1: Prepare the key
|
|
56
|
+
// If key is longer than block size, hash it first
|
|
57
|
+
// If shorter, it will be padded with zeros
|
|
58
|
+
let keyPrime;
|
|
59
|
+
if (key.length > BLOCK_SIZE) {
|
|
60
|
+
keyPrime = hash(key);
|
|
61
|
+
} else {
|
|
62
|
+
keyPrime = key;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Step 2: Create padded key blocks
|
|
66
|
+
const keyPadded = new Uint8Array(BLOCK_SIZE);
|
|
67
|
+
keyPadded.set(keyPrime);
|
|
68
|
+
// Remaining bytes are already 0 from Uint8Array initialization
|
|
69
|
+
|
|
70
|
+
// Step 3: Create inner and outer padded keys
|
|
71
|
+
const innerKey = new Uint8Array(BLOCK_SIZE);
|
|
72
|
+
const outerKey = new Uint8Array(BLOCK_SIZE);
|
|
73
|
+
|
|
74
|
+
for (let i = 0; i < BLOCK_SIZE; i++) {
|
|
75
|
+
innerKey[i] = keyPadded[i] ^ IPAD;
|
|
76
|
+
outerKey[i] = keyPadded[i] ^ OPAD;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Step 4: Compute inner hash: H((K' XOR ipad) || message)
|
|
80
|
+
const innerData = new Uint8Array(BLOCK_SIZE + data.length);
|
|
81
|
+
innerData.set(innerKey);
|
|
82
|
+
innerData.set(data, BLOCK_SIZE);
|
|
83
|
+
const innerHash = hash(innerData);
|
|
84
|
+
|
|
85
|
+
// Step 5: Compute outer hash: H((K' XOR opad) || innerHash)
|
|
86
|
+
const outerData = new Uint8Array(BLOCK_SIZE + 32);
|
|
87
|
+
outerData.set(outerKey);
|
|
88
|
+
outerData.set(innerHash, BLOCK_SIZE);
|
|
89
|
+
|
|
90
|
+
return hash(outerData);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Verify an HMAC-SHA256 digest
|
|
95
|
+
* Uses constant-time comparison to prevent timing attacks
|
|
96
|
+
*
|
|
97
|
+
* @param {Uint8Array} key - Secret key
|
|
98
|
+
* @param {Uint8Array} data - Message that was authenticated
|
|
99
|
+
* @param {Uint8Array} expectedMac - Expected HMAC digest to verify against
|
|
100
|
+
* @returns {boolean} True if MAC is valid, false otherwise
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* const isValid = verifyHmac(key, data, receivedMac);
|
|
104
|
+
* if (!isValid) {
|
|
105
|
+
* throw new Error('Message authentication failed');
|
|
106
|
+
* }
|
|
107
|
+
*/
|
|
108
|
+
function verifyHmac(key, data, expectedMac) {
|
|
109
|
+
if (!(expectedMac instanceof Uint8Array) || expectedMac.length !== 32) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const computedMac = hmacSha256(key, data);
|
|
114
|
+
return constantTimeEqual(computedMac, expectedMac);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Constant-time comparison of two byte arrays
|
|
119
|
+
* Prevents timing attacks by always comparing all bytes
|
|
120
|
+
*
|
|
121
|
+
* @param {Uint8Array} a - First array
|
|
122
|
+
* @param {Uint8Array} b - Second array
|
|
123
|
+
* @returns {boolean} True if arrays are equal
|
|
124
|
+
* @private
|
|
125
|
+
*/
|
|
126
|
+
function constantTimeEqual(a, b) {
|
|
127
|
+
if (a.length !== b.length) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
let result = 0;
|
|
132
|
+
for (let i = 0; i < a.length; i++) {
|
|
133
|
+
result |= a[i] ^ b[i];
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return result === 0;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
module.exports = {
|
|
140
|
+
hmacSha256,
|
|
141
|
+
verifyHmac,
|
|
142
|
+
BLOCK_SIZE
|
|
143
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Crypto Module
|
|
5
|
+
* Main exports for all cryptographic primitives and protocols.
|
|
6
|
+
* @module crypto
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// Hash functions
|
|
10
|
+
const { hash, createHash, HashContext } = require('./sha256');
|
|
11
|
+
const { hmacSha256, verifyHmac } = require('./hmac');
|
|
12
|
+
const { extract, expand, derive, deriveMultiple } = require('./hkdf');
|
|
13
|
+
|
|
14
|
+
// Symmetric encryption
|
|
15
|
+
const { chacha20, chacha20Block } = require('./chacha20');
|
|
16
|
+
const { poly1305 } = require('./poly1305');
|
|
17
|
+
const { encrypt, decrypt } = require('./aead');
|
|
18
|
+
|
|
19
|
+
// Asymmetric encryption (key exchange)
|
|
20
|
+
const { generateKeyPair, scalarMult, scalarMultBase } = require('./x25519');
|
|
21
|
+
|
|
22
|
+
// Noise Protocol
|
|
23
|
+
const noise = require('./noise');
|
|
24
|
+
|
|
25
|
+
// Key management
|
|
26
|
+
const keys = require('./keys');
|
|
27
|
+
|
|
28
|
+
module.exports = {
|
|
29
|
+
// SHA-256
|
|
30
|
+
hash,
|
|
31
|
+
createHash,
|
|
32
|
+
HashContext,
|
|
33
|
+
|
|
34
|
+
// HMAC
|
|
35
|
+
hmacSha256,
|
|
36
|
+
verifyHmac,
|
|
37
|
+
|
|
38
|
+
// HKDF
|
|
39
|
+
hkdfExtract: extract,
|
|
40
|
+
hkdfExpand: expand,
|
|
41
|
+
hkdf: derive,
|
|
42
|
+
hkdfMultiple: deriveMultiple,
|
|
43
|
+
|
|
44
|
+
// ChaCha20
|
|
45
|
+
chacha20,
|
|
46
|
+
chacha20Block,
|
|
47
|
+
|
|
48
|
+
// Poly1305
|
|
49
|
+
poly1305,
|
|
50
|
+
|
|
51
|
+
// AEAD (ChaCha20-Poly1305)
|
|
52
|
+
encrypt,
|
|
53
|
+
decrypt,
|
|
54
|
+
|
|
55
|
+
// X25519
|
|
56
|
+
generateKeyPair,
|
|
57
|
+
scalarMult,
|
|
58
|
+
scalarMultBase,
|
|
59
|
+
|
|
60
|
+
// Noise Protocol (as namespace)
|
|
61
|
+
noise,
|
|
62
|
+
|
|
63
|
+
// Key management (as namespace)
|
|
64
|
+
keys,
|
|
65
|
+
|
|
66
|
+
// Re-export commonly used classes at top level
|
|
67
|
+
NoiseHandshake: noise.NoiseHandshake,
|
|
68
|
+
NoiseSession: noise.NoiseSession,
|
|
69
|
+
SymmetricState: noise.SymmetricState,
|
|
70
|
+
KeyPair: keys.KeyPair,
|
|
71
|
+
KeyManager: keys.KeyManager
|
|
72
|
+
};
|