Merge branch 'master' into turdbo

This commit is contained in:
pdxlocations 2024-09-14 22:20:54 -07:00 committed by GitHub
commit 590d275aa5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
37 changed files with 689 additions and 287 deletions

View file

@ -0,0 +1,56 @@
---
title: "Meshtastic Encryption: Evolving from Simple Messaging to a Versatile Solution"
description: "Meshtastic's encryption has evolved, introducing our new Public Key Cryptography in v2.5.0 to enhance security in off-grid communication."
slug: introducing-new-public-key-cryptography-in-v2_5
authors: [Jonathan, crichton]
tags: [meshtastic, technical]
date: 2024-09-12T21:00
hide_table_of_contents: false
image: "/img/blog/Meshtastic_PKC_ECDH.png"
---
Meshtastic began with a straightforward goal: to keep hiking buddies connected in the outdoors when cell service was unavailable. What started as a simple project has grown, thanks to a passionate community pushing the boundaries of what's possible. Today, Meshtastic is used in Search and Rescue operations, off-grid communication, disaster recovery, and even grid-down scenarios. Whether it's preparing for the next flood or tornado, extending communication over the Internet with MQTT, or simply enjoying an off-grid adventure, Meshtastic has become an essential tool for many.
{/* truncate */}
### Balancing Encryption with Practical Use
For many, Meshtastic's encryption is a key part of the appeal. Over the years, the challenge has been finding a balance: implementing strong encryption without excluding low-power IoT platforms or overwhelming LoRa's limited bandwidth. Before version 2.5, encryption relied on a static pre-shared key per channel, which was quite robust. However, it had one notable limitation: Direct Messages (DMs).
DMs were sent using the same shared channel key, which meant that while DMs were theoretically private, they were accessible to anyone on the same channel. The honor system was the only safeguard, particularly since the default Meshtastic setup uses a publicly known encryption key, leaving DMs effectively unencrypted out of the box.
### Challenges with Remote Administration
Remote administration also presented hurdles. The conventional method involved creating an "admin" channel, allowing any node on that channel to be controlled remotely. This approach had drawbacks, notably that nodes open to administering others were also vulnerable to being administered themselves.
## Introducing Public Key Cryptography (PKC) to Meshtastic
In 2022, a user named edinnen proposed a solution with a pull request that introduced a public/private key scheme for DMs. Although the initial feedback was promising, the patch became outdated as time passed. Recently, everything aligned, and we revisited and reworked this patch, making it the foundation of Meshtastic's version 2.5 development.
Our new PKC implementation is now a core feature, providing each node with a unique public key generated at first boot. This key enables secure, encrypted connections between nodes and serves as a unique identifier within the mesh. It also solves the remote administration challenge—nodes can now be identified and authorized as remote administrators through their public keys.
### A Major Step Forward in Security
With this new PKC scheme, Meshtastic offers enhanced encryption for DMs and secure remote administration for difficult-to-reach nodes. While we still caution against relying solely on Meshtastic encryption for life-or-death situations, this update marks a significant advancement in privacy and security for the mesh network.
### Technical Deep Dive: The Mechanics of Meshtastic's New Encryption
At the heart of Meshtastic's new encryption system lies the X25519 elliptic curve Diffie-Hellman key exchange. This process unfolds in two key steps:
1. Key Generation: Upon first boot, each device generates a random private key and derives a corresponding public key using the X25519 algorithm. This public key is then broadcast to the mesh as part of the node's regular announcements.
2. Secure Communication: When a node initiates a Direct Message (DM), it completes the X25519 key exchange by combining its private key with the recipient's public key. This process generates a unique shared secret, which is then used to encrypt the DM. The receiving node can independently derive the same shared secret using its private key and the sender's public key, enabling secure decryption.
> ![Meshtastic's X25519 Key Exchange Process](/img/blog/Meshtastic_PKC_ECDH.png) Figure 1: Visual representation of Meshtastic's X25519 key exchange process
The encryption scheme employs AES-CCM (Counter with CBC-MAC), which provides both confidentiality and authenticity. A notable feature is the inclusion of a short Message Authentication Code, verifying the sender's identity and ensuring message integrity. To further enhance security, DM messages incorporate an additional 4 bytes of random nonce, effectively preventing potential compromises due to nonce reuse.
Remote administration has also seen significant improvements. Administration messages now include an 8-byte session key, set by the node being administered. This key is included in responses and must be present in any packet attempting to make changes. With a 300-second timeout, this mechanism provides robust protection against replay attacks of captured administration traffic.
## Conclusion
Meshtastic's journey from a simple hiking communication tool to a versatile, secure mesh networking solution showcases the power of community-driven development. The introduction of our new Public Key Cryptography scheme in version 2.5 represents a significant advancement in the platform's security capabilities, addressing long-standing challenges in direct messaging and remote administration.
As we continue to refine and expand Meshtastic's features, we remain committed to balancing robust security with practical usability. While this update significantly enhances the platform's privacy and security, we encourage users to approach encryption with a clear understanding of its strengths and limitations, especially in critical scenarios.
Looking ahead, we're excited about the possibilities this new encryption framework opens up. We invite our community to explore these new features, provide feedback, and continue pushing the boundaries of what's possible with Meshtastic. Together, we're building a more secure and connected future for off-grid communication.

View file

@ -19,4 +19,10 @@ GUVWAF:
image_url: https://github.com/GUVWAF.png
socials:
github: GUVWAF
Jonathan:
name: Jonathan Bennett
title: "Lead: The Linux Guy, Amateur Cryptographer, Position Wrangler, Privacy Protector, Bug Hunter"
url: https://github.com/jp-bennett
image_url: https://github.com/jp-bennett.png
socials:
github: jonathanbennett

View file

@ -76,9 +76,9 @@ If direct development contribution is not feasible for you, financial support is
</div>
</div>
### Fiscal Sponsorships
### Sponsors
We're deeply thankful for the backing from the Open Collective, Open Source Collective, DigitalOcean, and Vercel, which has been instrumental in our project's sustainability and growth:
We're deeply thankful for the backing from our sponsors, listed below, which has been instrumental in our project's sustainability and growth. Their support enables us to continue serving and expanding our community.
<div className="flex flex-wrap items-start">
<div className="w-full sm:w-3/12 p-3">
@ -86,8 +86,8 @@ We're deeply thankful for the backing from the Open Collective, Open Source Coll
alt="Open Collective"
className="max-h-8"
sources={{
light: useBaseUrl("/img/Open_Collective_logo_2021.svg"),
dark: useBaseUrl("/img/Open_Collective_logo_2021.svg"),
light: useBaseUrl("/img/contributing/Open_Collective_logo_2021.svg"),
dark: useBaseUrl("/img/contributing/Open_Collective_logo_2021.svg"),
}}
/>
</div>
@ -117,8 +117,8 @@ We're deeply thankful for the backing from the Open Collective, Open Source Coll
alt="Vercel"
className="max-h-8"
sources={{
light: useBaseUrl('/img/vercel-logotype-dark.svg'),
dark: useBaseUrl('/img/vercel-logotype-light.svg'),
light: useBaseUrl('/img/contributing/vercel-logotype-dark.svg'),
dark: useBaseUrl('/img/contributing/vercel-logotype-light.svg'),
}}
/>
</div>
@ -126,3 +126,18 @@ We're deeply thankful for the backing from the Open Collective, Open Source Coll
By covering our hosting costs, Vercel directly contributes to Meshtastic's growth, enhancing our web scalability and presence. Their sponsorship is crucial for our continued development and focus on creating a robust platform for decentralized communication.
</div>
</div>
<div className="flex flex-wrap items-start">
<div className="w-full sm:w-3/12 p-3">
<ThemedImage
alt="Datadog"
className="max-h-8"
sources={{
light: useBaseUrl("/img/contributing/dd_logo_h_rgb.svg"),
dark: useBaseUrl("/img/contributing/dd_logo_h_white.svg"),
}}
/>
</div>
<div className="w-full sm:w-9/12 p-3">
Datadog is an observability and security platform for cloud applications, providing infrastructure monitoring, application performance monitoring, and log management. They sponsor us by granting free infrastructure monitoring and logging, aiding our development and operational efforts.
</div>
</div>

View file

@ -29,7 +29,7 @@ Meshtastic utilizes LoRa, a long-range radio protocol, which is widely accessibl
These radios are designed to rebroadcast messages they receive, forming a mesh network. This setup ensures that every group member, including those at the furthest distance, can receive messages.
Additionally, Meshtastic radios can be paired with a single phone, allowing friends and family to send messages directly to your specific radio. It's important to note that each device is capable of supporting a connection from only one user at a time."
Additionally, Meshtastic radios can be paired with a single phone, allowing friends and family to send messages directly to your specific radio. It's important to note that each device is capable of supporting a connection from only one user at a time.
If you are interested in a more technical overview of how Meshtastic works, visit the overview section below:

View file

@ -1,151 +0,0 @@
---
id: encryption
title: Meshtastic Encryption
sidebar_label: Encryption
slug: /overview/encryption
sidebar_position: 3
description: "Understand Meshtastic's encryption: optional network-wide AES256 security for off-grid communication, ensuring confidentiality against passive eavesdropping."
---
## Explanation
Meshtastic provides AES256-CTR encryption for the payload of each packet when sending via LoRa, with a different key for each [channel](/docs/configuration/radio/channels/). The [packet header](/docs/overview/mesh-algo/#layer-1-unreliable-zero-hop-messaging) is always sent unencrypted, which allows nodes to relay packets they can't decrypt as well. One can disable this by setting a different [rebroadcast mode](/docs/configuration/radio/device#rebroadcast-mode).
By default you have one primary channel which is encrypted with a simple known key ("AQ=="), so to use proper encryption you **must change** this key first, or create a new channel and share it with the ones you want to communicate with. However, if you don't have the default key, it means you will not be able to communicate with devices that don't have your key.
Direct messages to a specific node (e.g. text, traceroute or position requests) may use any channel you share with the recipient. Namely, the device will use the one where it most recently heard a NodeInfo packet from the recipient on. Client apps will not show messages directed to other nodes, but in principle they could be read by **anyone** who knows the used channel key. This means that if it uses the default key, you have to assume anyone could read your direct messages.
All periodic broadcasts (position, telemetry, etc.) the device sends out itself are sent over the primary channel and thus encrypted with that key.
The device will decrypt the payload before sending it to a client app via BLE, serial, Wi-Fi/Ethernet. For MQTT you can [specify](/docs/configuration/module/mqtt#encryption-enabled) whether you want to send an encrypted or unencrypted payload.
## Is it as secure as Wi-Fi WPA3, HTTPS TLS1.3 or Signal ?
**No**.
[WPA3](https://en.wikipedia.org/wiki/WPA3), [TLS1.3](https://en.wikipedia.org/wiki/TLS1.3), [Signal](https://en.wikipedia.org/wiki/Signal_Protocol) and Meshtastic can all use AES256, yet AES is one of the many cogs required in a modern encryption system, see below the main features "missing" in Meshtastic.
### Perfect-Forward-Secrecy
[**P**erfect-**F**orward-**S**ecrecy also known as **PFS**](https://en.wikipedia.org/wiki/Forward_secrecy) means *previous* communications and more generally anything *passively captured* cannot be decrypted ***even when the key is compromised***.
This means Meshtastic is vulnerable to [**« Harvest now, Decrypt later »**](https://en.wikipedia.org/wiki/Harvest_now,_decrypt_later) attacks, **this attack itself is not enough to decrypt messages** it relies on an other failure leaking the channel key such as:
- Accidently sharing the channel key with the wrong person.
- One of your nodes being stolen.
- Any unknown bug revealing the channel key to an attacker.
Other protocols such as *misconfigured TLS1.2* are far more impacted by Harvest now, Decrypt later attacks because their keys will be broken by near future Quantum-Computers yet they do not provide PFS.
Meshtastic's encryption is not threatened by Quantum-Computers\* so realistic attack vectors are accidental miss-handling of channel keys and nodes being lost.
\*on the Quantum-Resistance of AES256 see:
- [this stackoverflow question, contain a bit of debates and two good answers](https://crypto.stackexchange.com/q/6712)
- [NIST's Post-Quantum FAQ](https://csrc.nist.gov/projects/post-quantum-cryptography/faqs) section « To protect against the threat of quantum computers, should we double the key length for AES now? (added 11/18/18) »
**Recommendations** for users using *private channels*:
- **Do not configure private channels on unattended nodes**, nodes will relay meshtastic traffic even if they are not able to decrypt it.
Your unattended routers should not have the private PSK configured as it is easy to gain physical access and extract the channel key.
- Keep in mind, everything sent on a channel can be stored and decrypted later by anyone who gain access to the key even if you locally delete the messages.
- Change your Channel Keys from time to time.
### Integrity
Integrity means ensuring messages cannot be modified without the key.
Meshtastic does not check messages have not been tempered with, see [`#4030`](https://github.com/meshtastic/firmware/issues/4030) for details.
**Recommendations**:
- Keep in mind, by applying a known plaintext attack anyone *could* send messages on a channel even with the channel key is private and secure.
- For developers of third party applications integrating meshtastic, include a cryptographic MAC over the message content and PSK,
we are also considering an [AEAD secured channel mode which would provide this natively](https://github.com/meshtastic/firmware/issues/4030).
### Authentication
Authentication means nodes say who they are on the network, meshtastic does not implement this so it is trivial to impersonate anyone else if you have access to the channel key.
This is because node ids are based on hardware [MAC address](https://en.wikipedia.org/wiki/MAC_address), theses are hardcoded by the manufacturer.
Some other networks like [Yggdrasil](https://yggdrasil-network.github.io/), [cjdns](https://github.com/cjdelisle/cjdns) or [libp2p](https://libp2p.io/) use [public / private key pairs](https://en.wikipedia.org/wiki/Public-key_cryptography) and the Public Key becomes the Node Identity, this make all messages bigger and or require an interactive handshake process.
**Recommendations**:
- Keep in mind, the sender field is indicative and anyone with access to the channel key can trivially lie.
## Direct-Messages
Direct-Messages are implemented as channel messages which have a `to` protobuf field set.
This means anyone in the channel can read all your direct-messages.
Also the node needs to know the right channel to use, this is done by using the latest one a NodeInfo was received, due to the lack of `Authentication` this means anyone you share a channel with can send a spoofed NodeInfo and make you send direct-messages on an incorrect public channel.
**Recommendations**:
- Keep in mind, due to NodeInfo spoof issue Direct-Messages are **very significantly less secure than a private channel** with a secure PSK.
- Do not use Direct-Messages for anything private, instead ahead of time create a new private channel and share it with the person you want to message with.
- Nodes will relay encrypted packets even if they can't decrypt it, so you only loose on some [small DM optimizations](https://github.com/meshtastic/firmware/pull/3753).
- Do not send the private channel key in direct messages or a public channel, because then anyone listening gain access.
- Use a different private channel for each person you want to have private conversations with.
## Comments
Cryptography is tricky, so we've tried to 'simply' apply standard crypto solutions to our implementation. However, the project developers are not cryptography experts.
Based on comments from reviewers (see below), here are some tips for usage of these radios, so that you may know the level of protection offered:
- It is pretty likely that the AES256 security is implemented 'correctly' and an observer will not be able to decode your messages.
- Warning: If an attacker is able to get one of the radios in their possession, they could either a) extract the channel key from that device or b) use that radio to listen to new communications.
- Warning: If an attacker is able to get the "Channel QR code/URL" that you share with others - that attacker could then be able to read any messages sent on the channel (either tomorrow or in the past - if they kept a raw copy of those broadcast packets)
The current implementation provides optional confidentiality to members of a configured network:
- Encryption is implemented in devices/nodes with network-wide encryption keys.
- Encryption is optional and is turned off when devices are in 'Ham mode'.
- There is no encryption supported in the clients (iOS, Android) to facilitate distribution as mass market software.
- Pairing from client-to-device is by:
- direct USB cable
- BT pairing
- Devices are 'promiscuous' and will pair with any near-by client. Network confidentiality requires physical protection of all nodes.
Always keep in mind [xkcd's note on encryption](https://xkcd.com/538).
- If you are a cryptography expert, please review these notes and our questions below. Can you help us by reviewing our notes below and offering advice? We will happily give as much or as little credit as you wish ;-).
- Consider our existing solution 'alpha' and probably fairly secure against a not particularly aggressive adversary (but we can't yet make a more confident statement).
### Notes for reviewers
If you are reviewing our implementation, this is a brief statement of our method.
- We do all crypto at the SubPacket (payload) level only, so that all Meshtastic nodes will route for others - even those channels which are encrypted with a different key.
- Mostly based on reading [Wikipedia](<https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_(CTR)>) and using the modes the ESP32 provides support for in hardware.
- We use AES256-CTR as a stream cypher (with zero padding on the last BLOCK) because it is well supported with hardware acceleration.
- Our AES key is 128 or 256 bits, shared as part of the 'Channel' specification.
- The node number concatenated with the packet number is used as the NONCE. This nonce will be stored in flash in the device and should essentially never repeat. If the user makes a new 'Channel' (i.e. picking a new random 256 bit key), the packet number will start at zero.
- The packet number is sent in cleartext with each packet. The node number can be derived from the "from" field of each packet. (Cleartext is acceptable because it merely provides IV for each encryption run)
- Each 16 byte BLOCK for a packet has an incrementing COUNTER. COUNTER starts at zero for the first block of each packet.
- The IV for each block is constructed by concatenating the NONCE as the upper 96 bits of the IV and the COUNTER as the bottom 32 bits. Since our packets are small counter portion will really never be higher than 32 (five bits).
### Comments from reviewer #1
This reviewer is a cryptography professional, but would like to remain anonymous. We thank them for their comments ;-):
I'm assuming that meshtastic is being used to hike in places where someone capable is trying to break it - like you were going to walk around DefCon using these. I spent about an hour reviewing the encryption, and have the following notes:
- The write-up isn't quite as clear as the code.
- The code is using AES-CTR mode correctly to ensure confidentiality.
- The comment for initNonce really covers the necessary information.
- I think the bigger encryption question is "what does the encryption need to do"? As it stands, an attacker who has yet to capture any of the devices cannot reasonably capture text or location data. An attacker who captures any device in the channel/mesh can read everything going to that device, everything stored on that device, and any other communication within the channel that they captured in encrypted form. If that capability basically matches your expectations, it is suitable for whatever adventures this was intended for, then, based on information publicly available or widely disclosed, the encryption is good. If those properties are distressing (like, device history is deliberately limited and you don't want a device captured today to endanger the information sent over the channel yesterday) we could talk about ways to achieve that (most likely synchronizing time and replacing the key with its own SHA256 every X hours, and ensuring the old key is not retained unnecessarily).
- Two other things to keep in mind are that AES-CTR does not itself provide authenticity (e.g. an attacker can flip bits in replaying data and scramble the resulting plaintext), and that the current scheme gives some hints about transmission in the size. So, if you worry about an adversary deliberately messing-up messages or knowing the length of a text message, it looks like those might be possible.
I'm guessing that the network behaves somewhat like a store-and-forward network - or, at least, that the goal is to avoid establishing a two-way connection to transmit data. I'm afraid I haven't worked with mesh networks much, but remember studying them briefly in school about ten years ago.
### Comments from @Jorropo
- The IV initialization only use 31 random bits per reboot, it then increment messages sequentially. This is not high, it makes duplicate unlikely but probable given the complete scale of the network. Thankfully IV include lower 32 bits of the MAC address which should be unique per node, so each node is it's own birthday paradox, we aren't looking for network wide birthday paradox which would be easy to hack. See [`#4031`](https://github.com/meshtastic/firmware/issues/4031).
Could be fixed.
- The lack of [integrity wasn't properly considered](https://github.com/meshtastic/firmware/issues/4030), the remote administration module implements priviliged RPC calls over AES-CTR without any MAC or AEAD.
Could be fixed.
- The AES-CTR implementation looks like it protects Confidentiality assuming IVs are not duplicated.
- The lack of Forward Secrecy is a bit worrying for a chat messenger when new users lack the paranoid and annoying key management practice that would be required for safe operation.
- IMO the clients should have a big red box the first time you open a Direct-Message indicating theses are not private and not E2E. This was not clear to me without reading the code.
- This project is completely fine for chatting with strangers, using the default key and understanding everything is public, I would not trust it with anything private without some other layer or significant reworks. For example I would consider SSH or Signal over Meshtastic safe. Yet Meshtastic does not choose to have worse crypto for bad reasons, they make the network significantly more usable over the unreliable slow LoRa backhaul it is using.

View file

@ -0,0 +1,72 @@
---
id: comments
title: Comments on Meshtastic's Encryption
sidebar_label: Comments
sidebar_position: 2
description: "Explore community insights and expert opinions on Meshtastic's encryption, including AES256 implementation, security tips, and potential vulnerabilities."
---
This page compiles community feedback and expert reviews on Meshtastic's encryption approach. We value these insights and aim to improve our encryption implementation where feasible. Explore key details, practical tips, and understand the strengths and potential limitations of Meshtastic's AES256 encryption.
## Comments
Cryptography is tricky, so we've tried to 'simply' apply standard crypto solutions to our implementation. However, the project developers are not cryptography experts.
Based on comments from reviewers (see below), here are some tips for using these radios, so that you may know the level of protection offered:
- It is likely that the AES256 security is implemented 'correctly' and an observer will not be able to decode your messages.
- **Warning:** If an attacker is able to get one of the radios in their possession, they could either a) extract the channel key from that device, or b) use that radio to listen to new communications.
- **Warning:** If an attacker is able to get the "Channel QR code/URL" that you share with others, that attacker could then be able to read any messages sent on the channel (either tomorrow or in the past - if they kept a raw copy of those broadcast packets).
The current implementation provides optional confidentiality to members of a configured network:
- Encryption is implemented in devices/nodes with network-wide encryption keys.
- Encryption is optional and is turned off when devices are in 'Ham mode'.
- There is no encryption supported in the clients (iOS, Android) to facilitate distribution as mass-market software.
- Pairing from client-to-device is by:
- Direct USB cable
- BT pairing
- Devices are 'promiscuous' and will pair with any nearby client. Network confidentiality requires physical protection of all nodes.
Always keep in mind [xkcd's note on encryption](https://xkcd.com/538).
- If you are a cryptography expert, please review these notes and our questions below. Can you help us by reviewing our notes below and offering advice? We will happily give as much or as little credit as you wish ;-).
- Consider our existing solution 'alpha' and probably fairly secure against a not particularly aggressive adversary (but we can't yet make a more confident statement).
## Notes for reviewers
If you are reviewing our implementation, this is a brief statement of our method.
- We do all crypto at the SubPacket (payload) level only, so that all Meshtastic nodes will route for others - even those channels which are encrypted with a different key.
- Mostly based on reading [Wikipedia](<https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_(CTR)>) and using the modes the ESP32 provides support for in hardware.
- We use AES256-CTR as a stream cypher (with zero padding on the last BLOCK) because it is well supported with hardware acceleration.
- Our AES key is 128 or 256 bits, shared as part of the 'Channel' specification.
- The node number concatenated with the packet number is used as the NONCE. This nonce will be stored in flash in the device and should essentially never repeat. If the user makes a new 'Channel' (i.e. picking a new random 256 bit key), the packet number will start at zero.
- The packet number is sent in cleartext with each packet. The node number can be derived from the "from" field of each packet. (Cleartext is acceptable because it merely provides IV for each encryption run)
- Each 16 byte BLOCK for a packet has an incrementing COUNTER. COUNTER starts at zero for the first block of each packet.
- The IV for each block is constructed by concatenating the NONCE as the upper 96 bits of the IV and the COUNTER as the bottom 32 bits. Since our packets are small counter portion will really never be higher than 32 (five bits).
### Comments from reviewer #1
This reviewer is a cryptography professional, but would like to remain anonymous. We thank them for their comments ;-):
I'm assuming that meshtastic is being used to hike in places where someone capable is trying to break it - like you were going to walk around DefCon using these. I spent about an hour reviewing the encryption, and have the following notes:
- The write-up isn't quite as clear as the code.
- The code is using AES-CTR mode correctly to ensure confidentiality.
- The comment for initNonce really covers the necessary information.
- I think the bigger encryption question is "what does the encryption need to do"? As it stands, an attacker who has yet to capture any of the devices cannot reasonably capture text or location data. An attacker who captures any device in the channel/mesh can read everything going to that device, everything stored on that device, and any other communication within the channel that they captured in encrypted form. If that capability basically matches your expectations, it is suitable for whatever adventures this was intended for, then, based on information publicly available or widely disclosed, the encryption is good. If those properties are distressing (like, device history is deliberately limited and you don't want a device captured today to endanger the information sent over the channel yesterday) we could talk about ways to achieve that (most likely synchronizing time and replacing the key with its own SHA256 every X hours, and ensuring the old key is not retained unnecessarily).
- Two other things to keep in mind are that AES-CTR does not itself provide authenticity (e.g. an attacker can flip bits in replaying data and scramble the resulting plaintext), and that the current scheme gives some hints about transmission in the size. So, if you worry about an adversary deliberately messing-up messages or knowing the length of a text message, it looks like those might be possible.
I'm guessing that the network behaves somewhat like a store-and-forward network - or, at least, that the goal is to avoid establishing a two-way connection to transmit data. I'm afraid I haven't worked with mesh networks much, but remember studying them briefly in school about ten years ago.
### Comments from @Jorropo
- The IV initialization only use 31 random bits per reboot, it then increment messages sequentially. This is not high, it makes duplicate unlikely but probable given the complete scale of the network. Thankfully IV include lower 32 bits of the MAC address which should be unique per node, so each node is it's own birthday paradox, we aren't looking for network wide birthday paradox which would be easy to hack. See [`#4031`](https://github.com/meshtastic/firmware/issues/4031).
Could be fixed.
- The lack of [integrity wasn't properly considered](https://github.com/meshtastic/firmware/issues/4030), the remote administration module implements priviliged RPC calls over AES-CTR without any MAC or AEAD.
Could be fixed.
- The AES-CTR implementation looks like it protects Confidentiality assuming IVs are not duplicated.
- The lack of Forward Secrecy is a bit worrying for a chat messenger when new users lack the paranoid and annoying key management practice that would be required for safe operation.
- IMO the clients should have a big red box the first time you open a Direct-Message indicating theses are not private and not E2E. This was not clear to me without reading the code.
- This project is completely fine for chatting with strangers, using the default key and understanding everything is public, I would not trust it with anything private without some other layer or significant reworks. For example I would consider SSH or Signal over Meshtastic safe. Yet Meshtastic does not choose to have worse crypto for bad reasons, they make the network significantly more usable over the unreliable slow LoRa backhaul it is using.

View file

@ -0,0 +1,115 @@
---
id: encryption
title: Meshtastic Encryption
sidebar_label: Encryption
slug: /overview/encryption
sidebar_position: 3
description: "Understand Meshtastic's encryption: optional network-wide AES256 security for off-grid communication, ensuring confidentiality against passive eavesdropping."
---
## Explanation
Meshtastic provides AES256-CTR encryption for the payload of each packet when sending via LoRa, with a different key for each [channel](/docs/configuration/radio/channels/). The [packet header](/docs/overview/mesh-algo/#layer-1-unreliable-zero-hop-messaging) is always sent unencrypted, which allows nodes to relay packets they can't decrypt as well. One can disable this by setting a different [rebroadcast mode](/docs/configuration/radio/device#rebroadcast-mode).
By default, you have one primary channel, which is encrypted with a simple known key ("AQ=="), so to use proper encryption, you **must change** this key first, or create a new channel and share it with the ones you want to communicate with. However, if you don't have the default key, it means you will not be able to communicate with devices that don't have your key.
Direct messages to a specific node are now encrypted using Public Key Cryptography (PKC). Each node is equipped with a unique public/private key pair, and direct messages are encrypted with the recipient's public key. This ensures that only the recipient can decrypt the message using their private key. Additionally, messages are signed with the sender's private key, allowing the recipient to verify the sender's identity and ensuring the message's integrity.
All periodic broadcasts (position, telemetry, traceroutes, etc.) the device sends out itself are sent over the primary channel and thus encrypted with that key.
The device will decrypt the payload before sending it to a client app via BLE, serial, Wi-Fi/Ethernet. For MQTT, you can [specify](/docs/configuration/module/mqtt#encryption-enabled) whether you want to send an encrypted or unencrypted payload.
## Is it as secure as Wi-Fi WPA3, HTTPS TLS1.3, or Signal?
**No**.
[WPA3](https://en.wikipedia.org/wiki/WPA3), [TLS1.3](https://en.wikipedia.org/wiki/TLS1.3), [Signal](https://en.wikipedia.org/wiki/Signal_Protocol), and Meshtastic can all use AES256. Yet AES is one of the many cogs required in a modern encryption system. Below are the main features "missing" in Meshtastic.
### Perfect-Forward-Secrecy
[**P**erfect-**F**orward-**S**ecrecy, also known as **PFS**](https://en.wikipedia.org/wiki/Forward_secrecy), means _previous_ communications and more generally anything _passively captured_ cannot be decrypted **_even when the key is compromised_**.
This means Meshtastic is vulnerable to [**« Harvest now, Decrypt later »**](https://en.wikipedia.org/wiki/Harvest_now,_decrypt_later) attacks. **This attack itself is not enough to decrypt messages**; it relies on another failure leaking the channel key, such as:
- Accidentally sharing the channel key with the wrong person.
- One of your nodes being stolen.
- Any unknown bug revealing the channel key to an attacker.
Other protocols, such as _misconfigured TLS1.2_, are far more impacted by Harvest now, Decrypt later attacks because their keys will be broken by near-future Quantum-Computers, yet they do not provide PFS.
Meshtastic's AES256 encryption is considered quantum-resistant[^1], but the public/private key exchange for DMs is not, as current quantum-resistant cryptography schemes don't fit in LoRa packets or our IoT hardware; realistic attack vectors include accidental mishandling of channel keys, nodes being lost, and potential future quantum attacks on DM key exchanges.
[^1]: On the Quantum-Resistance of AES256, see [this stackoverflow question, containing a bit of debate and two good answers](https://crypto.stackexchange.com/q/6712) and the [NIST's Post-Quantum FAQ](https://csrc.nist.gov/projects/post-quantum-cryptography/faqs) section "To protect against the threat of quantum computers, should we double the key length for AES now? (added 11/18/18)"
#### Recommendations for users using private channels
- **Do not configure private channels on unattended nodes**. Nodes will relay Meshtastic traffic even if they are not able to decrypt it. Your unattended routers should not have the private PSK configured as it is easy to gain physical access and extract the channel key.
- Keep in mind that everything sent on a channel can be stored and decrypted later by anyone who gains access to the key, even if you locally delete the messages.
- Change your Channel Keys from time to time.
#### Changes since 2.5.0 Firmware release
- Direct Messages are now protected with PKC when messaging between devices on v2.5.0 or newer and key exchange has taken place, messaging to legacy 2.4.3 or older firmware versions are not protected.
- Admin Messages between two v2.5.0 or newer nodes are now protected and additonal relay attack protection in place.
### Integrity
Integrity means ensuring messages cannot be modified without the key.
Meshtastic does not verify the integrity of channel messages to check if they have been tampered with (see [issue #4030](https://github.com/meshtastic/firmware/issues/4030) for details).
#### Recommendations
- Keep in mind that by applying a known plaintext attack, anyone _could_ send messages on a channel even if the channel key is private and secure.
- For developers of third-party applications integrating Meshtastic, include a cryptographic MAC over the message content and PSK. We are also considering an [AEAD secured channel mode which would provide this natively](https://github.com/meshtastic/firmware/issues/4030).
#### Changes since 2.5.0 Firmware release
- Message integrity is checked for Direct Messages or Admin Control when communication is between v2.5.0 or newer firmware.
### Authentication
Authentication means nodes say who they are on the network. Meshtastic does not implement this, so it is trivial to impersonate anyone else if you have access to the channel key
This is because node IDs are based on hardware [MAC address](https://en.wikipedia.org/wiki/MAC_address), which are hardcoded by the manufacturer.
Some other networks like [Yggdrasil](https://yggdrasil-network.github.io/), [cjdns](https://github.com/cjdelisle/cjdns), or [libp2p](https://libp2p.io/) use [public/private key pairs](https://en.wikipedia.org/wiki/Public-key_cryptography), and the Public Key becomes the Node Identity. This makes all messages bigger and/or requires an interactive handshake process.
#### Recommendations
- Keep in mind that the sender field is indicative, and anyone with access to the channel key can trivially lie.
#### Changes since 2.5.0 Firmware release
- The above now only relates to group chats/channels as DM's are protected when messaging between devices on 2.5 or newer, messaging to legacy 2.4 or older devices are not afforded this addition authentication.
## Direct Messages
Direct Messages (DMs) are now implemented using Public Key Cryptography (PKC). This provides a significant upgrade in security compared to the previous channel-based encryption:
- **Message Encryption:** Each DM is encrypted using the recipient's public key, ensuring that only the recipient can decrypt the message with their private key.
- **Digital Signatures:** Messages are signed with the sender's private key, allowing the recipient to verify the sender's identity and ensuring the integrity of the message.
### Prior to 2.5.0 Firmware Release
Previously, DMs were implemented as channel messages with a `to` protobuf field set. This meant anyone in the channel could read all your direct messages. With PKC, this issue is resolved, as only the intended recipient can decrypt and read the message.
### Recommendations
- While PKC significantly enhances the security of DMs, it's still advisable to avoid sharing sensitive information in direct messages without proper verification of the recipient's public key.
## Admin Messages
Admin Messages/Control are now protected by enhanced security features, making sure that critical operations within the network are more secure than ever before.
- **Stronger Encryption:** Admin Messages now use advanced encryption methods to ensure that only the intended recipients can access and read them.
- **Session IDs:** Each administrative session is assigned a unique Session ID, which helps prevent unauthorized access and ensures that messages are not tampered with or replayed.
### Prior to 2.5.0 Firmware Release
Previously, admin messages were not as secure, but with these updates, they are now much better protected against potential attacks and replay attacks.
### Recommendations
- Always ensure that your devices are using the latest firmware to benefit from these improved security features.
- Regularly monitor your network for any unusual activity to maintain a high level of security.

View file

@ -79,6 +79,10 @@ us on [Discord](https://discord.com/invite/ktMAKGBnBs) to add your group.
- [Mesht Saskatchewan](https://t.me/MeshtSaska)
## Denmark
- [Danske Meshtastic Brugere](https://discord.gg/EXWWwDmfBN)
## Finland
- [Mesh Finland Discord](https://discord.com/invite/GHnaVAjqed)

View file

@ -10,11 +10,10 @@ import TabItem from "@theme/TabItem";
If your device is connected to Internet via wifi or ethernet, you can enable it to forward packets along to an MQTT server. This allows users on the local mesh to communicate with users on the internet. One or more channels must also be enabled as uplink and/or downlink for packets to be transmitted from and/or to your mesh (See [channels](/docs/configuration/radio/channels#downlink-enabled)). Without these settings enabled, the node will still connect to the MQTT server but only send status messages.
The MQTT module config options are: Enabled, Server Address, Username, Password, Encryption Enabled, JSON Enabled, TLS Enabled, Root Topic, Client Proxy Enabled, Map Reporting Enabled (with Position Precision and Publish Interval). MQTT Module config uses an admin message sending a `ConfigModule.MQTT` protobuf.
The MQTT module config options are: Enabled, Server Address, Username, Password, Encryption Enabled, JSON Enabled, TLS Enabled, Root Topic, Client Proxy Enabled, Map Reporting Enabled (with Position Precision and Publish Interval), and Okay to MQTT. MQTT Module config uses an admin message sending a `ConfigModule.MQTT` protobuf.
## Settings
## MQTT Module Config Values
### Enabled
@ -56,27 +55,40 @@ If true, we attempt to establish a secure connection using TLS.
The root topic to use for MQTT messages. This is useful if you want to use a single MQTT server for multiple meshtastic networks and separate them via ACLs.
### Client Proxy Enabled
If true, let the device use the client's (e.g. your phone's) network connection to connect to the MQTT server. If false, it uses the device's network connection which you have to enable via the [network settings](/docs/configuration/radio/network).
### Map Reporting Enabled
Available from firmware version 2.3.2 on.
If true, your node will periodically send an unencrypted map report to the MQTT server to be displayed by online maps that support this packet. This report includes the following information:
- The node's long and short name and ID;
- The node's position (with configurable precision) and altitude;
- The node's hardware model and [role](/docs/configuration/radio/device/#roles);
- The node's firmware version;
- The node's LoRa region, modem preset and primary channel name;
- The node's LoRa region, modem preset and primary channel name;
- Whether the node can be reached on the default channel with known key;
- Number of local online nodes (heard in the last 2 hours, excluding those heard via MQTT).
#### Map Report Position Precision
The precision to use for the position in the map report. Defaults to a maximum deviation of around 1459m.
#### Map Report Publish Interval
How often we should publish the map report to the MQTT server in seconds. Defaults to 900 seconds (15 minutes).
### OK to MQTT
Acceptable values: `true`, `false`
Default is `false`. When set to `true`, this configuration indicates that the user approves the packet to be uploaded to MQTT. If set to `false`, remote nodes are requested not to forward packets to MQTT.
**Important:** This is not a cryptographic solution but a polite request that is enforced in the official firmware.
## MQTT Module Config Client Availability
<Tabs
groupId="settings"
defaultValue="apple"
@ -121,18 +133,19 @@ The following configuration options are available in the Python CLI:
:::
| Setting | Acceptable Values | Default |
| :--------------------------: | :---------------: | :-----------------: |
| mqtt.enabled | `true`, `false` | `false` |
| mqtt.address | `string` |`mqtt.meshtastic.org`|
| mqtt.username | `string` | `meshdev` |
| mqtt.password | `string` | `large4cats` |
| mqtt.encryption_enabled | `true`, `false` | `false` |
| mqtt.json_enabled | `true`, `false` | `false` |
| mqtt.tls_enabled | `true`, `false` | `false` |
| mqtt.root | `string` | |
| mqtt.proxy_to_client_enabled | `true`, `false` | `false` |
| mqtt.map_reporting_enabled | `true`, `false` | `false` |
| Setting | Acceptable Values | Default |
| :--------------------------: | :---------------: | :-------------------: |
| mqtt.enabled | `true`, `false` | `false` |
| mqtt.address | `string` | `mqtt.meshtastic.org` |
| mqtt.username | `string` | `meshdev` |
| mqtt.password | `string` | `large4cats` |
| mqtt.encryption_enabled | `true`, `false` | `false` |
| mqtt.json_enabled | `true`, `false` | `false` |
| mqtt.tls_enabled | `true`, `false` | `false` |
| mqtt.root | `string` | |
| mqtt.proxy_to_client_enabled | `true`, `false` | `false` |
| mqtt.map_reporting_enabled | `true`, `false` | `false` |
| mqtt.config_ok_to_mqtt | `true`, `false` | `false` |
:::tip
@ -191,7 +204,7 @@ Navigate to: Vertical Ellipsis (3 dots top right) > Radio configuration > MQTT:
[![MQTT Settings](/img/modules/mqtt/android_mqtt_encryption_sm.webp)](/img/modules/mqtt/android_mqtt_encryption.webp)
*Optional:* To use your phone's internet connection to send and receive packets over the web, also enable the slider for **MQTT Client Proxy** and skip the Configure Network Settings step below.
_Optional:_ To use your phone's internet connection to send and receive packets over the web, also enable the slider for **MQTT Client Proxy** and skip the Configure Network Settings step below.
[![Client Proxy](/img/modules/mqtt/android_mqtt_proxy_sm.webp)](/img/modules/mqtt/android_mqtt_proxy_encryption.webp)
@ -219,7 +232,7 @@ Navigate to Settings > MQTT: Turn on the slider for MQTT enabled and tap **Save*
[![MQTT Settings 1](/img/modules/mqtt/apple_mqtt_1_encryption_sm.webp)](/img/modules/mqtt/apple_mqtt_1_encryption.webp)
[![MQTT Settings 2](/img/modules/mqtt/apple_mqtt_2_sm.webp)](/img/modules/mqtt/apple_mqtt_2.webp)
*Optional:* To use your phone's internet connection to send and receive packets over the web, also enable the slider for **MQTT Client Proxy** and skip the Configure Network Settings step below.
_Optional:_ To use your phone's internet connection to send and receive packets over the web, also enable the slider for **MQTT Client Proxy** and skip the Configure Network Settings step below.
[![Client Proxy](/img/modules/mqtt/apple_mqtt_1_proxy_sm.webp)](/img/modules/mqtt/apple_mqtt_1_proxy_encryption.webp)
@ -254,6 +267,7 @@ meshtastic --ch-set downlink_enabled true --ch-index 0
```
or chained together:
```shell
meshtastic --ch-set uplink_enabled true --ch-index 0 --ch-set downlink_enabled true --ch-index 0
```
@ -267,6 +281,7 @@ meshtastic --set network.wifi_psk yourpassword
```
or chained together:
```shell
meshtastic --set network.wifi_enabled true --set network.wifi_ssid "your network" --set network.wifi_psk yourpassword
```
@ -282,7 +297,7 @@ Navigate to Config > Module Config > MQTT - Turn on the slider for MQTT enabled
[![MQTT Settings](/img/modules/mqtt/web_mqtt_encryption_sm.webp)](/img/modules/mqtt/web_mqtt_encryption.webp)
*Optional:* To use your client's internet connection to send and receive packets over the web, also enable the slider for **Proxy to Client Enabled** and skip the Configure Network Settings step below.
_Optional:_ To use your client's internet connection to send and receive packets over the web, also enable the slider for **Proxy to Client Enabled** and skip the Configure Network Settings step below.
[![Client Proxy](/img/modules/mqtt/web_mqtt_proxy_sm.webp)](/img/modules/mqtt/web_mqtt_proxy_encryption.webp)
@ -292,7 +307,6 @@ Though this option may be visible in your UI, Client Proxy is not yet functional
:::
##### 2. Enable Channel Uplink & Downlink
Navigate to Channels > Primary: Turn on the sliders for **Uplink Enabled** and **Downlink Enabled** - Click the **Save** icon.

View file

@ -79,24 +79,12 @@ This setting defines the device's behavior for how messages are rebroadcasted.
| `LOCAL_ONLY` | LOCAL_ONLY - Ignores observed messages from foreign meshes that are open or those which it cannot decrypt. Only rebroadcasts message on the nodes local primary / secondary channels. |
| `KNOWN_ONLY` | KNOWN_ONLY - Ignores observed messages from foreign meshes like LOCAL_ONLY, but takes it a step further by also ignoring messages from nodenums not in the node's known list (NodeDB). |
## Serial Console
Acceptable values: `true` or `false`
Disabling this will disable the SerialConsole by not initializing the StreamAPI.
## TZDEF (Timezone Definition)
The `tzdef` setting allows the local offset to be defined for the device. It uses the TZ Database format to display the correct local time on the device display and in its logs.
To set the timezone, use the POSIX TZ Database string for the relevant region. Here is a list of [supported timezones](https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv). For example, if your region is `America/Los_Angeles`, you would input `PST8PDT,M3.2.0,M11.1.0` as the timezone.
## Debug Log
Acceptable values: `true` or `false`
By default we turn off logging as soon as an API client connects. Set this to true to leave the debug log outputting even when API is active.
## GPIO for user button
This is the GPIO pin number that will be used for the user button, if your device does not come with a predefined user button.
@ -113,10 +101,6 @@ This is the number of seconds between NodeInfo message (containing i.a. long and
This option will enable a double tap, when a supported accelerometer is attached to the device, to be treated as a button press.
## Managed Mode
Enabling Managed mode will restrict access to all radio configurations via client applications. Radio configurations will only be accessible through the Admin channel. To avoid being locked out, make sure the Admin channel is working properly before enabling it.
## Device Config Client Availability
<Tabs
@ -161,24 +145,21 @@ All device config options are available in the python CLI. Example commands are
:::
| Setting | Acceptable Values | Default |
| --------------------------------- | ----------------------------------------------------------------------------------- | ----------------- |
| device.debug_log_enabled | `true`, `false` | `false` |
| Setting | Acceptable Values | Default |
| --------------------------------- | ------------------------------------------------------------------ | ----------------- |
| device.role | `CLIENT`, `CLIENT_MUTE`, `ROUTER`, `REPEATER`, `TRACKER`, `SENSOR` | `CLIENT` |
| device.rebroadcast_mode | `ALL`, `ALL_SKIP_DECODING`, `LOCAL_ONLY` | `ALL` |
| device.serial_enabled | `true`, `false` | `true` |
| device.button_gpio | `0` - `34` | `0` |
| device.buzzer_gpio | `0` - `34` | `0` |
| device.node_info_broadcast_secs | `3600` - `UINT MAX` | `10800` (3 hours) |
| device.double_tap_as_button_press | `false`, `true` | `false` |
| device.is_managed | `false`, `true` | `false` |
| device.rebroadcast_mode | `ALL`, `ALL_SKIP_DECODING`, `LOCAL_ONLY` | `ALL` |
| device.button_gpio | `0` - `34` | `0` |
| device.buzzer_gpio | `0` - `34` | `0` |
| device.node_info_broadcast_secs | `3600` - `UINT MAX` | `10800` (3 hours) |
| device.double_tap_as_button_press | `false`, `true` | `false` |
:::tip
Because the device will reboot after each command is sent via CLI, it is recommended when setting multiple values in a config section that commands be chained together as one.
```shell title="Example:"
meshtastic --set device.role CLIENT --set device.debug_log_enabled true
meshtastic --set device.role CLIENT --set device.tzdef UTC0
```
:::
@ -187,18 +168,10 @@ meshtastic --set device.role CLIENT --set device.debug_log_enabled true
meshtastic --set device.role CLIENT
```
```shell title="Disable serial console"
meshtastic --set device.serial_enabled false
```
```shell title="Set tzdef"
meshtastic --set device.tzdef UTC0
```
```shell title="Enable debug logging"
meshtastic --set device.debug_log_enabled true
```
</TabItem>
<TabItem value="web">

View file

@ -0,0 +1,127 @@
---
id: security
title: Security Configuration
sidebar_label: Security
description: This section covers security options for the device such public key, privaate key, and admin key
---
import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
The security config options are: Public Key, Private Key, Admin Key, Is Managed, Serial Console, Debug Logs, and Admin Channel.
## Security Config Values
### Public Key
Acceptable values: `bytes`
The public key of the device, shared with other nodes on the mesh to allow them to compute a shared secret key for secure communication.
### Private Key
Acceptable values: `bytes`
The private key of the device, used to create a shared key with a remote device for secure communication.**This key should be kept confidential.**
### Admin Key
Acceptable values: `repeated bytes`
The public key(s) authorized to send administrative messages to this node. Only messages signed by these keys will be accepted for administrative control.
### Managed Mode
Acceptable values: `true` or `false`
Enabling Managed Mode restricts access to all radio configurations via client applications. Radio configurations will only be accessible through the Admin channel. Ensure the Admin channel is functioning properly before enabling this mode to avoid being locked out.
### Serial Console
Acceptable values: `true` or `false`
Disabling this will prevent the Serial Console from initializing the Stream API.
### Debug Log
Acceptable values: `true` or `false`
By default, logging is disabled when an API client connects to keep the shared serial link quiet. Set this to true to continue outputting live debug logs over serial or Bluetooth when the API is active.
### Admin Channel Enabled
Acceptable values: `true` or `false`
Allows incoming device control over the insecure legacy admin channel. Enabling this option permits control messages to be received through the older, less secure admin channel.
## Device Config Client Availability
<Tabs
groupId="settings"
defaultValue="apple"
values={[
{label: 'Android', value: 'android'},
{label: 'Apple', value: 'apple'},
{label: 'CLI', value: 'cli'},
{label: 'Web', value: 'web'},
]}>
<TabItem value="android">
#### Android
All Security config options are available for Android.
1. Open the Meshtastic App
2. Navigate to: **Vertical Ellipsis (3 dots top right) > Radio Configuration > Security**
</TabItem>
<TabItem value="apple">
#### Apple
All Security config options are available on iOS, iPadOS and macOS at Settings > Radio Configuration > Security.
</TabItem>
<TabItem value="cli">
#### CLI
All Security config options are available in the python CLI. Example commands are below:
| Setting | Acceptable Values | Default |
| ------------------------------ | ----------------- | ------- |
| security.public_key | `bytes` | `None` |
| security.private_key | `bytes` | `None` |
| security.admin_key | `repeated bytes` | `None` |
| security.is_managed | `true`, `false` | `false` |
| security.serial_enabled | `true`, `false` | `true` |
| security.debug_log_api_enabled | `true`, `false` | `false` |
| security.admin_channel_enabled | `true`, `false` | `false` |
:::tip
Because the device may reboot after each command is sent via CLI, it is recommended when setting multiple values in a config section that commands be chained together as one.
```shell title="Example:"
meshtastic --set security.is_managed false --set device.debug_log_api_enabled true
```
:::
```shell title="Disable serial console"
meshtastic --set security.serial_enabled false
```
```shell title="Enable debug logging"
meshtastic --set security.debug_log_api_enabled true
```
</TabItem>
<TabItem value="web">
#### Web
All Security config options are available in the Web client.
</TabItem>
</Tabs>

View file

@ -11,16 +11,18 @@ The device might report these fault codes on the screen, but it will also be out
This table is derived from the [protobufs](https://buf.build/meshtastic/protobufs/docs/main:meshtastic#meshtastic.CriticalErrorCode)
:::
| Name | Number | Description |
| :-----------------: | :----: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| TxWatchdog | 1 | A software bug was detected while trying to send LoRa |
| SleepEnterWait | 2 | A software bug was detected on entry to sleep |
| NoRadio | 3 | No LoRa radio hardware could be found |
| Unspecified | 4 | Not normally used |
| UBloxInitFailed | 5 | We failed while configuring a UBlox GPS |
| NoAXP192 | 6 | This board was expected to have a power management chip and it is missing or broken |
| InvalidRadioSetting | 7 | The channel tried to set a radio setting which is not supported by this chipset, radio comms settings are now undefined |
| TransmitFailed | 8 | Radio transmit hardware failure. We sent data to the radio chip, but it did not reply with an interrupt |
| Brownout | 9 | We detected that the main CPU voltage dropped below the minimum acceptable value |
| SX1262Failure | 10 | Selftest of SX1262 radio chip failed |
| RadioSpiBug | 11 | A (likely software but possibly hardware) failure was detected while trying to send packets. If this occurs on your board, please post in the forum so that we can ask you to collect some information to allow fixing this bug |
| Name | Number | Description |
| :--------------------------: | :----: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| TxWatchdog | 1 | A software bug was detected while trying to send LoRa. |
| SleepEnterWait | 2 | A software bug was detected on entry to sleep. |
| NoRadio | 3 | No LoRa radio hardware could be found. |
| Unspecified | 4 | Not normally used. |
| UBloxInitFailed | 5 | Failed while configuring a UBlox GPS. |
| NoAXP192 | 6 | This board was expected to have a power management chip, but it is missing or broken. |
| InvalidRadioSetting | 7 | The channel tried to set a radio setting not supported by this chipset; radio communication settings are now undefined. |
| TransmitFailed | 8 | Radio transmit hardware failure. Data was sent to the radio chip, but it did not respond with an interrupt. |
| Brownout | 9 | Main CPU voltage dropped below the minimum acceptable value. |
| SX1262Failure | 10 | Self-test of the SX1262 radio chip failed. |
| RadioSpiBug | 11 | A failure (likely software, possibly hardware) was detected while sending packets. If this occurs on your board, please post in the forum to help us collect information to fix this bug. |
| FlashCorruptionRecoverable | 12 | Corruption was detected on the flash filesystem, but it was repaired. |
| FlashCorruptionUnrecoverable | 13 | Corruption was detected on the flash filesystem, and it could not be repaired. _Note: Your node will likely need reconfiguration upon the next reboot (e.g., loss of region code)._ |

View file

@ -4,10 +4,6 @@ title: Serving Docs Locally for Development
sidebar_label: Local Development
---
:::note
Some things won't display properly like logos or protobufs page, this is not cause for concern.
:::
## Prerequisites
In order to set up your local environment, you will need to install:
@ -24,17 +20,23 @@ Log into GitHub and create a fork of the [meshtastic/meshtastic](https://github.
### Clone your Meshtastic Repository fork
:::note
Replace `username` with your GitHub username.
Replace `YOUR_GITHUB_USERNAME` with your GitHub username.
:::
```shell title="Clone username/Meshtastic Repo"
git clone https://github.com/username/meshtastic.git
```shell title="Clone your Fork of the Documentation Repository"
git clone https://github.com/YOUR_GITHUB_USERNAME/meshtastic.git
```
### Change directory to Local copy
### Change directory into your Local Copy
```shell title="Change Directory"
cd ~/meshtastic
cd ./meshtastic
```
### Install Submodules
```shell title="Install Submodules"
git submodule update --init --recursive
```
### Install Dependencies

View file

@ -0,0 +1,78 @@
---
id: encryption-technical
title: Updated Security Implementation
sidebar_label: Encryption Technical
sidebar_position: 5
description: Technical Overview of Encryption Employed with Meshtastic from Firmware 2.5.0 Onwards
---
## PSK for Channels, PKC for Direct Messages (DMs) and Admin Messages
Starting with firmware version 2.5.0, which introduces Public Key Cryptography (PKC) for Direct Messages (DMs) and additionally incorporating the use of Session IDs for Admin Messages, the security architecture of Meshtastic has reached a new level of robustness.
Below is a detailed overview of how PSK, PKC, and Session IDs are integrated into your system to secure Channels, Direct Messages, and Admin Messages.
### 1. Chat Channels Using Pre-Shared Key (PSK)
- **PSK Overview:**
- Chat Channels continue to utilize a Pre-Shared Key (PSK) for encrypting communications.
- All participants share the same PSK for their Channels, which is used for both encryption and decryption within the channel.
- **Security Considerations:**
- **Confidentiality:** Only participants with the correct PSK can access messages within the Chat Channel.
- **Key Management:** Secure distribution and regular rotation of the PSK are essential to maintaining the channel's security.
### 2. Direct Messages (DMs) Now Using PKC
- **PKC Implementation for DMs:**
- **Public/Private Key Pairs:** Each node is equipped with a unique public/private key pair. The private key is securely stored on the node, and the public key is shared with other nodes, allowing for secure, authenticated communication.
- **Encryption and Signature:**
- **Encryption:** DMs are encrypted using the recipients public key, ensuring only the recipient with the corresponding private key can decrypt the message.
- **Digital Signatures:** Messages are signed with the senders private key before encryption, allowing the recipient to verify the senders identity and the messages integrity using the senders public key.
- **Security Enhancements with PKC:**
- **Message Confidentiality and Integrity:** With PKC, each DM is encrypted and signed, ensuring that only the intended recipient can read the message, and verifying that it has not been tampered with.
### 3. Admin Messages: Enhanced Security with PKC and Session IDs
- **Key Exchange with DH Curve25519:**
- **Initial Key Exchange Setup:**
- **Key Generation:** A Diffie-Hellman (DH) key exchange occurs using Curve25519 upon first communication between nodes. This generates a shared secret for establishing a symmetric encryption key.
- **Hardware Support:** Curve25519 is supported in hardware, ensuring efficient and secure key exchanges.
- **Shared Secret:** The derived shared secret is used for all subsequent communications between the nodes.
- **Use of Shared Secret for Encryption:**
- **Symmetric Encryption:** Following the key exchange, messages are encrypted and decrypted using the shared secret with symmetric encryption algorithms like AES-CTR or AES-CCM.
- **Efficiency:** Symmetric encryption, especially when based on a secure DH exchange, balances security and performance, making it ideal for real-time applications.
- **Session ID for Admin Messages:**
- **Session ID Usage:** Session IDs are generated for each admin session and used as an additional value inside the encrypted packet. This ensures that each session is secure and unique.
- **Session Duration:** The session ID is valid only for a short duration (e.g., 300 seconds) and is discarded once the session ends or after the next control message is sent.
- **Security Enhancements with PKC and Session ID:**
- **Replay Attack Mitigation:** By utilizing session IDs, replay attacks are effectively mitigated. Old session IDs cannot be reused, ensuring that intercepted packets are invalidated.
- **Isolated Impact:** The use of session IDs confines any issues related to session management to admin messages, without affecting broader communication functions like DMs or Chat Channels.
### 4. Overall Security Architecture
- **Integration of PKC with Existing Systems:**
- **Direct Messages:** PKC enhances the security of DMs by providing encryption, authentication, and integrity through the use of asymmetric encryption and digital signatures.
- **Admin Messages:** The combination of PKC and session IDs secures admin-related operations, providing an additional layer of protection for critical functions.
- **Use of PSK with Existing Systems:**
- **Channels:** PSKs continue to be used for group communication, ensuring secure message exchanges within the channel.
- **Scalability and Performance:**
- **Efficient Use of Resources:** PKC for DMs leverages asymmetric encryption for secure communication, while PSKs for Chat Channels and session IDs for admin messages optimize resource consumption on the platform.
- **Memory Management:** The selective use of PKC, PSKs, and session IDs ensures that memory and computational resources are effectively managed, allowing the system to scale while maintaining high security.
## Conclusion
PSKs and the expanded use of PKC and session IDs across different MCU architectures—ESP32, nRF52, and ARM—demonstrates a tailored approach to security that balances performance, power consumption, and memory management. Each architecture's strengths are leveraged to ensure that secure communications are maintained without compromising the efficiency or scalability of the system. This approach provides robust security for a wide range of applications, from low-power wearable devices to more powerful, feature-rich systems.

View file

@ -14,7 +14,8 @@ Inexpensive basic ESP32-based boards.
| [LoRa32 V2.1](./lora32/?heltec=v2.1) | ESP32 | SX127x | 2.4GHz b/g/n | 4.2 | NO |
| [LoRa32 V3/3.1](./lora32/?heltec=v23) | ESP32-S3FN8 | SX1262 | 2.4GHz b/g/n | 5.0 | NO |
| [Wireless Stick Lite V3](./lora32/?heltec=Wireless+Stick+Lite+V3) | ESP32-S3FN8 | SX1262 | 2.4GHz b/g/n | 5.0 | NO |
| [Wireless Tracker](./lora32/?heltec=tracker) | ESP32-S3FN8 | SX1262 | 2.4GHz b/g/n | 5.0 | YES |
| [Wireless Tracker v1.0](./lora32/?heltec=tracker-v1.0) | ESP32-S3FN8 | SX1262 | 2.4GHz b/g/n | 5.0 | YES |
| [Wireless Tracker v1.1](./lora32/?heltec=tracker-v1.1) | ESP32-S3FN8 | SX1262 | 2.4GHz b/g/n | 5.0 | YES |
| [Wireless Paper](./lora32/?heltec=paper) | ESP32-S3FN8 | SX1262 | 2.4GHz b/g/n | 5.0 | NO |
## [Plug & Play Sensors](./sensor/)

View file

@ -16,7 +16,8 @@ values={[
{label: 'LoRa32 V2.1', value: 'v2.1'},
{label: 'LoRa32 V3/V3.1', value:'v3'},
{label: 'Wireless Stick Lite V3', value:'Wireless Stick Lite V3'},
{label: 'Wireless Tracker', value: 'tracker'},
{label: 'Wireless Tracker v1.0', value: 'tracker-v1.0'},
{label: 'Wireless Tracker v1.1', value: 'tracker-v1.1'},
{label: 'Wireless Paper v1.0', value: 'paper-v1.0'},
{label: 'Wireless Paper v1.1', value: 'paper-v1.1'}
]}>
@ -165,9 +166,73 @@ Image Source: [Heltec](https://resource.heltec.cn/download/Wireless_Stick_Lite_V
</TabItem>
<TabItem value="tracker">
<TabItem value="tracker-v1.0">
## Wireless Tracker
## Wireless Tracker v1.0
:::info
This device may have issues charging a connected battery if utilizing a USB-C to USB-C cable. It's recommended to use a USB-A to USB-C cable.
:::
- **MCU:**
- ESP32-S3FN8 (WiFi & Bluetooth)
- **LoRa Transceiver:**
- Semtech SX1262
- **Frequency Options:**
- 470 - 510 MHz
- 863 - 870 MHz
- 902 - 928 MHz
- **Connectors:**
- USB-C
- Antenna:
- Dedicated 2.4 GHz metal spring antenna for WiFi/Bluetooth
- U.FL/IPEX antenna connector for LoRa and GNSS
### Features
- Onboard 0.96-inch LCD display
- User and Reset Buttons
### Flashing
To flash ESP32-S3 devices like the Wireless Tracker, you typically need to place them in Espressif's firmware download mode. Use the "1200bps reset" button in the web flasher to do this. If this method does not work for any reason, you can follow the manual process below.
:::warning
Do not proceed unless an antenna is connected to avoid possible damage to the device's radio.
:::
The following process will manually place the device into the Espressif Firmware Download mode:
1. Unplug the device.
2. Press and hold the USER button.
3. Plug device in.
4. After 2-3 seconds, release the USER button.
With the device now in the Espressif Firmware Download mode, you can proceed with flashing using one of the supported flashing methods. It's generally recommended to use the [Web Flasher](https://flasher.meshtastic.org/). You can select "Heltec Wireless Tracker" from the device drop-down.
### Pin Map
![HT-Tracker_V1 Pin Map](/img/hardware/HT-Tracker_V1_Pin_Map.webp)
Image Source: [Heltec](https://heltec.org/project/wireless-tracker/)
### Resources
- Firmware file: `firmware-heltec-wireless-tracker-V1-0-X.X.X.xxxxxxx.bin`
- Purchase Links:
:::note
Heltec revised the Wireless Tracker schematics and released a V1.1, most devices being sold are now [V1.1.](/docs/hardware/devices/heltec-automation/lora32/?heltec=tracker-v1.1#resources-4)
:::
</TabItem>
<TabItem value="tracker-v1.1">
## Wireless Tracker v1.1
:::info
This device may have issues charging a connected battery if utilizing a USB-C to USB-C cable. It's recommended to use a USB-A to USB-C cable.

View file

@ -126,7 +126,8 @@ Inexpensive basic ESP32-based boards.
| [LoRa32 V2.1](./heltec-automation/lora32/?heltec=v2.1) | ESP32 | SX127x | 2.4GHz b/g/n | 4.2 | NO |
| [LoRa32 V3/3.1](./heltec-automation/lora32/?heltec=v23) | ESP32-S3FN8 | SX1262 | 2.4GHz b/g/n | 5.0 | NO |
| [Wireless Stick Lite V3](./heltec-automation/lora32/?heltec=Wireless+Stick+Lite+V3) | ESP32-S3FN8 | SX1262 | 2.4GHz b/g/n | 5.0 | NO |
| [Wireless Tracker](./heltec-automation/lora32/?heltec=tracker) | ESP32-S3FN8 | SX1262 | 2.4GHz b/g/n | 5.0 | YES |
| [Wireless Tracker v1.0](./heltec-automation/lora32/?heltec=tracker-v1.0) | ESP32-S3FN8 | SX1262 | 2.4GHz b/g/n | 5.0 | YES |
| [Wireless Tracker v1.1](./heltec-automation/lora32/?heltec=tracker-v1.1) | ESP32-S3FN8 | SX1262 | 2.4GHz b/g/n | 5.0 | YES |
| [Wireless Paper](./heltec-automation/lora32/?heltec=paper) | ESP32-S3FN8 | SX1262 | 2.4GHz b/g/n | 5.0 | NO |
### [Plug & Play Sensors](./heltec-automation/sensor/)
@ -189,6 +190,8 @@ Meshtastic offers support for Raspberry Pi devices through our Linux native plat
### SenseCap
The SenseCAP product line offers a comprehensive range of solutions for both hobbyists and industrial users, featuring the T1000-E card tracker, an IP65-rated, ready-to-go Meshtastic device, and the Indicator with a 4-inch touchscreen driven by ESP32-S3 and RP2040 Dual-MCU, coming soon.
| Name | MCU | Radio | WiFi | BT | GPS |
| ------------------------------------------------------------- | ------------- | ------ | ---- | --- | --- |
| [Card Tracker T1000-E](./seeed-studio/sensecap/card-tracker/) | nRF52840 | LR1110 | NO | 5.1 | YES |

View file

@ -115,6 +115,8 @@ Webserver:
Port: 443 # Port for Webserver & Webservices
RootPath: /usr/share/doc/meshtasticd/web # Root Dir of WebServer
```
### Bluetooth Support
Bluetooth is currently unsupported and not functional on Linux Native devices. This may change in the future.
### GPS Support

View file

@ -7,13 +7,16 @@ sidebar_position: 6
Seeed Studio is a tech company focused on Edge AI and IoT. With the mission of "making technology accessible for all", Seeed Studio has been embracing open source since DAY 1. Seeed works closely with the Meshtastic community to bring easy-to-use, affordable products to community members. By listening to the voices, communicating and collaborating closely with innovators in this community, iterations of products and new services are brought to life.
### SenseCap
### [SenseCap](./sensecap/)
The SenseCAP product line offers a comprehensive range of solutions for both hobbyists and industrial users, featuring the T1000-E card tracker, an IP65-rated, ready-to-go Meshtastic device, and the Indicator with a 4-inch touchscreen driven by ESP32-S3 and RP2040 Dual-MCU, coming soon.
| Name | MCU | Radio | WiFi | BT | GPS |
| ------------------------------------------------ | ------------- | ------ | ---- | --- | --- |
| [Card Tracker T1000-E](./sensecap/card-tracker/) | nRF52840 | LR1110 | NO | 5.1 | YES |
| [SenseCAP Indicator](#) (coming soon) | ESP32, RP2040 | - | - | - | - |
### [Wio-WM1110](./wm1110)
nRF52840-based development boards with GPS, and multiple ports to attach sensors.

View file

@ -10,7 +10,7 @@ SenseCAP T1000-E is a high-performance tracker designed for Meshtastic. As small
### Specifications
- **MCU**
- Nordic nRF52840 (WiFi & Bluetooth)
- Nordic nRF52840 (supports Bluetooth)
- **LoRa Transceiver**
- Semtech LR1110
- **Frequency options**
@ -34,8 +34,9 @@ SenseCAP T1000-E is a high-performance tracker designed for Meshtastic. As small
- Purchase Links:
- International
- [Seeed Studio](https://www.seeedstudio.com/SenseCAP-Card-Tracker-T1000-E-for-Meshtastic-p-5913.html)
- [User Guide](https://wiki.seeedstudio.com/sensecap_t1000_e/)
#### Images
![SenseCAP Card Tracker T1000-E for Meshtastic](/img/hardware/seeed/card_tracker.webp)
![SenseCAP Card Tracker T1000-E Dimensions](/img/hardware/seeed/T1000-E.webp)
![SenseCAP Card Tracker T1000-E for Meshtastic](/img/hardware/seeed/t1000-e-meshtastic.webp)
![SenseCAP Card Tracker T1000-E Dimensions](/img/hardware/seeed/t1000-e-hardware.webp)

View file

@ -70,7 +70,7 @@ The LR1110 GNSS functionality does not yet work. Seeed recommends at Grove - GPS
## Wio Tracker 1110 Dev Kit for Meshtastic
- **MCU**
- Nordic nRF52840 (WiFi & Bluetooth)
- Nordic nRF52840 (BLE 5.3)
- **LoRa Transceiver**
- Semtech LR1110
- **Frequency options**

View file

@ -53,3 +53,5 @@ This process ensures transparency and community involvement in the granting of t
- Details: Simon is a Meshtastic designer of devices, device enclosures and accessories that carry the "Meshtastic" , Meshtastic.org URL and "M" logos. The use of the Meshtastic Logo and Trademarks does not imply Simon is sponsored or endorsed by Meshtastic. Simon also agrees to maintain compliance with the Meshtastic Legal requirements. This grant is revokable at any time for any reason.
- Grant: [Rokland LLC](https://www.rokland.com)
- Details: Rokland LLC is a Meshtastic contributor/distributor of parts and devices that run Meshtastic firmware. The Meshtastic "M" logo will be used on a promotional give-away t-shirt to promote the RAKwireless WisMesh Pocket product. The use of the Meshtastic Logo and Trademarks does not imply Rokland LLC is sponsored or endorsed by Meshtastic. Rokland LLC also agrees to maintain compliance with the Meshtastic Legal requirements. This grant is revokable at any time for any reason.
- Grant: Meshtastic Solutions LLC
- Details: Meshtastic Solutions LLC is a company focused on Meshtastic Research and Development and expanding Meshtastic into new industries. Meshtastic Solutions LLC is granted use of all Meshtastic logos and trademarks. Meshtastic Solutions LLC agrees to maintain compliance with all Meshtastic Legal requirements.

View file

@ -323,8 +323,9 @@ export const FrequencyCalculator = (): JSX.Element => {
return (
<div className="flex flex-col border-l-[5px] shadow-md my-4 border-accent rounded-lg p-4 bg-secondary gap-2">
<div className="flex gap-2">
<label>Modem Preset:</label>
<label htmlFor="modemPreset">Modem Preset:</label>
<select
id="modemPreset"
value={modemPreset}
onChange={(e) =>
setModemPreset(
@ -342,8 +343,9 @@ export const FrequencyCalculator = (): JSX.Element => {
</select>
</div>
<div className="flex gap-2">
<label>Region:</label>
<label htmlFor="region">Region:</label>
<select
id="region"
value={region}
onChange={(e) => setRegion(Number.parseInt(e.target.value))}
>
@ -354,15 +356,21 @@ export const FrequencyCalculator = (): JSX.Element => {
))}
</select>
</div>
<div className="flex gap-2 mb-4">
<label className="font-semibold">Number of slots:</label>
<input type="number" disabled={true} value={numChannels} />
<label htmlFor="numSlots" className="font-semibold">
Number of slots:
</label>
<input
id="numSlots"
type="number"
disabled={true}
value={numChannels}
/>
</div>
<div className="flex gap-2">
<label>Frequency Slot:</label>
<label htmlFor="frequencySlot">Frequency Slot:</label>
<select
id="frequencySlot"
value={channel}
onChange={(e) => setChannel(Number.parseInt(e.target.value))}
>
@ -373,10 +381,16 @@ export const FrequencyCalculator = (): JSX.Element => {
))}
</select>
</div>
<div className="flex gap-2">
<label className="font-semibold">Frequency of slot:</label>
<input type="number" disabled={true} value={channelFrequency} />
<label htmlFor="slotFrequency" className="font-semibold">
Frequency of slot:
</label>
<input
id="slotFrequency"
type="number"
disabled={true}
value={channelFrequency}
/>
</div>
</div>
);

View file

@ -280,4 +280,4 @@ p {
.markdown img {
margin-bottom: 0;
}
}

View file

@ -1,46 +1,46 @@
.accordion {
border-radius: 2px;
border: 1px solid var(--ifm-color-emphasis-200);
border-radius: 2px;
border: 1px solid var(--ifm-color-emphasis-200);
}
.accordion__item + .accordion__item {
border-top: 1px solid var(--ifm-color-emphasis-200);
border-top: 1px solid var(--ifm-color-emphasis-200);
}
.accordion__button {
background-color: var(--ifm-footer-background-color);
border: none;
cursor: pointer;
padding: calc(var(--ifm-pre-padding)/1.5);
text-align: left;
width: 100%;
background-color: var(--ifm-footer-background-color);
border: none;
cursor: pointer;
padding: calc(var(--ifm-pre-padding) / 1.5);
text-align: left;
width: 100%;
}
.accordion__button:hover {
background-color: var(--ifm-background-surface-color);
background-color: var(--ifm-background-surface-color);
}
.accordion__button:before {
border-bottom: 2px solid currentColor;
border-right: 2px solid currentColor;
content: '';
display: inline-block;
height: 10px;
margin-right: 12px;
transform: rotate(-45deg);
width: 10px;
border-bottom: 2px solid currentColor;
border-right: 2px solid currentColor;
content: "";
display: inline-block;
height: 10px;
margin-right: 12px;
transform: rotate(-45deg);
width: 10px;
}
.accordion__button[aria-expanded='true']::before,
.accordion__button[aria-selected='true']::before {
transform: rotate(45deg);
.accordion__button[aria-expanded="true"]::before,
.accordion__button[aria-selected="true"]::before {
transform: rotate(45deg);
}
[hidden] {
display: none;
display: none;
}
.accordion__panel {
background: var(--ifm-background-color);
padding: var(--ifm-pre-padding);
background: var(--ifm-background-color);
padding: var(--ifm-pre-padding);
}

View file

@ -1 +0,0 @@
<svg width="457" height="60" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path d="M34.62 18.179C36.75 21.249 38 24.979 38 29s-1.25 7.75-3.38 10.821L29.697 34.9A12.16 12.16 0 0 0 31.214 29c0-2.14-.55-4.15-1.516-5.9l4.921-4.921ZM29.82 13.38 24.9 18.302A12.16 12.16 0 0 0 19 16.786c-6.746 0-12.214 5.468-12.214 12.214S12.254 41.214 19 41.214c2.14 0 4.15-.55 5.9-1.516l4.921 4.921A18.912 18.912 0 0 1 19 48C8.507 48 0 39.493 0 29s8.507-19 19-19c4.021 0 7.75 1.25 10.821 3.38Z" fill="#7FADF2"/><path d="M34.62 18.179C36.75 21.249 38 24.979 38 29s-1.25 7.75-3.38 10.821L29.697 34.9A12.16 12.16 0 0 0 31.214 29c0-2.14-.55-4.15-1.516-5.9l4.921-4.921Z" fill="#B8D3F4"/><g fill="#515F71"><path d="M110.7 13.6c-3.7 0-7.2 1.4-9.8 3.6v-2.3c0-.6-.5-1-1-1h-3.4c-.6 0-1 .5-1 1v43.7c0 .5.4 1 1 1h3.5c.5 0 1-.4 1-1V40.3c2.6 2.2 6.1 3.6 9.8 3.6 8.4 0 15.2-6.8 15.2-15.2-.2-8.4-7-15.1-15.3-15.1Zm0 24.8c-5.4 0-9.7-4.4-9.7-9.7 0-5.4 4.4-9.7 9.7-9.7 5.4 0 9.7 4.4 9.7 9.7 0 5.4-4.4 9.7-9.7 9.7ZM176.6 13.6c-3.7 0-7.1 1.3-9.7 3.5v-1.3c0-1.1-.9-2-2-2h-1.5c-1.1 0-2 .9-2 2v26.3c0 .8.7 1.5 1.5 1.5h2.5c.8 0 1.5-.7 1.5-1.5V29.6c0-5.4 4.4-10.6 9.7-10.6 3.5 0 9.7 1.9 9.7 10.6v12.5c0 .8.7 1.5 1.5 1.5h2.5c.8 0 1.5-.7 1.5-1.5V29.5c0-13.2-10.4-15.9-15.2-15.9ZM158.2 25.5c-1.5-7.1-8-12.3-15.6-11.9-7.6.4-13.8 6.4-14.3 14-.6 8.9 6.4 16.3 15.1 16.3 5.9 0 11-3.3 13.5-8.2.4-.7-.1-1.6-.9-1.8l-3-.6c-.5-.1-1 .1-1.3.6-1.7 2.7-4.8 4.6-8.2 4.6-3 0-5.7-1.4-7.5-3.5l17.2-7.2 5-2.3Zm-24.4 4.4c0-.4-.1-.8-.1-1.2 0-5.4 4.4-9.7 9.7-9.7 3 0 5.8 1.4 7.5 3.6l-17.1 7.3ZM77.3 13.4c-8.4 0-15.2 6.8-15.2 15.2 0 8.4 6.8 15.2 15.2 15.2 8.4 0 15.2-6.8 15.2-15.2 0-8.4-6.8-15.2-15.2-15.2Zm0 24.9c-5.4 0-9.7-4.4-9.7-9.7 0-5.4 4.4-9.7 9.7-9.7 5.4 0 9.7 4.4 9.7 9.7.1 5.3-4.3 9.7-9.7 9.7ZM258.7 13.3c-8.4 0-15.2 6.8-15.2 15.2 0 8.4 6.8 15.2 15.2 15.2 8.4 0 15.2-6.8 15.2-15.2 0-8.4-6.8-15.2-15.2-15.2Zm0 24.9c-5.4 0-9.7-4.4-9.7-9.7 0-5.4 4.4-9.7 9.7-9.7 5.4 0 9.7 4.4 9.7 9.7 0 5.3-4.3 9.7-9.7 9.7ZM390.6 4.3h-3.1c-.7 0-1.2.5-1.2 1.2v3.1c0 .7.5 1.2 1.2 1.2h3.1c.7 0 1.2-.5 1.2-1.2V5.5c0-.7-.6-1.2-1.2-1.2ZM454.5 33.7l-3.6-.7c-.4-.1-.8.1-1 .5-1.7 2.8-4.8 4.7-8.3 4.7-3 0-5.7-1.4-7.5-3.5l17.2-7.2 5.2-2.2c-1.5-7.1-8-12.3-15.6-11.9-7.6.4-13.8 6.5-14.3 14.1-.6 8.9 6.4 16.3 15.1 16.3 6 0 11.2-3.5 13.6-8.5.2-.8-.2-1.5-.8-1.6Zm-22.7-5.3c0-5.4 4.4-9.7 9.7-9.7 3 0 5.8 1.4 7.5 3.6l-17.2 7.3v-1.2ZM332 25.2c-1.5-7.1-8-12.3-15.6-11.9-7.6.4-13.8 6.5-14.3 14.1-.6 8.9 6.4 16.3 15.1 16.3 6 0 11.2-3.5 13.7-8.6.3-.6-.1-1.3-.7-1.4l-3.6-.7c-.4-.1-.8.1-1 .5-1.7 2.8-4.8 4.7-8.3 4.7-3 0-5.7-1.4-7.5-3.5l17.2-7.2 5-2.3Zm-24.5 4.4c0-.4-.1-.8-.1-1.2 0-5.4 4.4-9.7 9.7-9.7 3 0 5.8 1.4 7.5 3.6l-17.1 7.3ZM283.2.7h-3.6c-.5 0-.9.4-.9.9v40.7c0 .5.4 1 1 1h3.5c.5 0 1-.4 1-1V1.6c0-.5-.5-.9-1-.9ZM295.5.7h-3.6c-.5 0-.9.4-.9.9v40.7c0 .5.4 1 1 1h3.5c.5 0 1-.4 1-1V1.6c-.1-.5-.5-.9-1-.9ZM390.6 13.4h-3.1c-.7 0-1.2.5-1.2 1.2v27.6c0 .7.5 1.2 1.2 1.2h3.1c.7 0 1.2-.5 1.2-1.2V14.5c0-.6-.6-1.1-1.2-1.1ZM380.4 13.4h-3.9c-.4 0-.8-.4-.8-.8V1.5c0-.4-.4-.8-.8-.8H371c-.4 0-.8.4-.8.8v11.1c0 .4-.4.8-.8.8h-3.9c-.4 0-.8.4-.8.8V18c0 .4.4.8.8.8h3.9c.4 0 .8.4.8.8v22.7c0 .6.5 1 1 1h3.4c.6 0 1-.5 1-1V19.6c0-.4.4-.8.8-.8h3.9c.4 0 .8-.4.8-.8v-3.9c.1-.4-.2-.7-.7-.7ZM358.8 35.5c-.4-.4-1.1-.4-1.5 0-1.8 1.7-4.1 2.7-6.8 2.7-5.7 0-10.3-5-9.7-10.8.5-4.5 4.2-8.1 8.7-8.6 2.8-.3 5.5.7 7.4 2.4.6.5 1.5.5 2.1-.1l1.7-1.7c.6-.6.6-1.6 0-2.2-2.9-2.7-6.9-4.2-11.2-3.9-7.7.5-13.9 6.9-14.2 14.7-.3 8.6 6.6 15.6 15.2 15.6 4.1 0 7.9-1.6 10.6-4.3.4-.4.4-1.1 0-1.5l-2.3-2.3ZM239.1 35.5c-.4-.4-1.1-.4-1.5 0-1.8 1.7-4.1 2.7-6.8 2.7-5.7 0-10.3-5-9.7-10.8.5-4.5 4.2-8.1 8.7-8.6 2.8-.3 5.5.7 7.4 2.4.6.5 1.5.5 2.1-.1l1.7-1.7c.6-.6.6-1.6 0-2.2-2.9-2.7-6.9-4.2-11.2-3.9-7.7.5-13.9 6.9-14.2 14.7-.3 8.6 6.6 15.6 15.2 15.6 4.1 0 7.9-1.6 10.6-4.3.4-.4.4-1.1 0-1.5l-2.3-2.3ZM424 13.7h-4.9c-.1 0-.2.1-.2.2l-8 23.5c-.1.2-.4.2-.4 0l-8-23.5c0-.1-.1-.2-.2-.2h-4.9c-.2 0-.3.2-.2.3l9.9 29.1c0 .1.1.2.2.2h6.8c.1 0 .2-.1.2-.2l9.9-29.1c.1-.1 0-.3-.2-.3Z"/></g></g></svg>

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="457" height="60"><g fill="none" fill-rule="evenodd"><path fill="#7FADF2" d="M34.62 18.179C36.75 21.249 38 24.979 38 29s-1.25 7.75-3.38 10.821L29.697 34.9a12.16 12.16 0 0 0 1.517-5.9c0-2.14-.55-4.15-1.516-5.9zm-4.8-4.799-4.92 4.922a12.16 12.16 0 0 0-5.9-1.516c-6.746 0-12.214 5.468-12.214 12.214S12.254 41.214 19 41.214c2.14 0 4.15-.55 5.9-1.516l4.921 4.921A18.9 18.9 0 0 1 19 48C8.507 48 0 39.493 0 29s8.507-19 19-19c4.021 0 7.75 1.25 10.821 3.38Z"/><path fill="#B8D3F4" d="M34.62 18.179C36.75 21.249 38 24.979 38 29s-1.25 7.75-3.38 10.821L29.697 34.9a12.16 12.16 0 0 0 1.517-5.9c0-2.14-.55-4.15-1.516-5.9z"/><path fill="#515F71" d="M110.7 13.6c-3.7 0-7.2 1.4-9.8 3.6v-2.3c0-.6-.5-1-1-1h-3.4c-.6 0-1 .5-1 1v43.7c0 .5.4 1 1 1h3.5c.5 0 1-.4 1-1V40.3c2.6 2.2 6.1 3.6 9.8 3.6 8.4 0 15.2-6.8 15.2-15.2-.2-8.4-7-15.1-15.3-15.1m0 24.8c-5.4 0-9.7-4.4-9.7-9.7 0-5.4 4.4-9.7 9.7-9.7 5.4 0 9.7 4.4 9.7 9.7 0 5.4-4.4 9.7-9.7 9.7m65.9-24.8c-3.7 0-7.1 1.3-9.7 3.5v-1.3c0-1.1-.9-2-2-2h-1.5c-1.1 0-2 .9-2 2v26.3c0 .8.7 1.5 1.5 1.5h2.5c.8 0 1.5-.7 1.5-1.5V29.6c0-5.4 4.4-10.6 9.7-10.6 3.5 0 9.7 1.9 9.7 10.6v12.5c0 .8.7 1.5 1.5 1.5h2.5c.8 0 1.5-.7 1.5-1.5V29.5c0-13.2-10.4-15.9-15.2-15.9m-18.4 11.9c-1.5-7.1-8-12.3-15.6-11.9s-13.8 6.4-14.3 14c-.6 8.9 6.4 16.3 15.1 16.3 5.9 0 11-3.3 13.5-8.2.4-.7-.1-1.6-.9-1.8l-3-.6c-.5-.1-1 .1-1.3.6-1.7 2.7-4.8 4.6-8.2 4.6-3 0-5.7-1.4-7.5-3.5l17.2-7.2zm-24.4 4.4c0-.4-.1-.8-.1-1.2 0-5.4 4.4-9.7 9.7-9.7 3 0 5.8 1.4 7.5 3.6zM77.3 13.4c-8.4 0-15.2 6.8-15.2 15.2s6.8 15.2 15.2 15.2S92.5 37 92.5 28.6s-6.8-15.2-15.2-15.2m0 24.9c-5.4 0-9.7-4.4-9.7-9.7 0-5.4 4.4-9.7 9.7-9.7 5.4 0 9.7 4.4 9.7 9.7.1 5.3-4.3 9.7-9.7 9.7m181.4-25c-8.4 0-15.2 6.8-15.2 15.2s6.8 15.2 15.2 15.2 15.2-6.8 15.2-15.2-6.8-15.2-15.2-15.2m0 24.9c-5.4 0-9.7-4.4-9.7-9.7 0-5.4 4.4-9.7 9.7-9.7 5.4 0 9.7 4.4 9.7 9.7s-4.3 9.7-9.7 9.7M390.6 4.3h-3.1c-.7 0-1.2.5-1.2 1.2v3.1c0 .7.5 1.2 1.2 1.2h3.1c.7 0 1.2-.5 1.2-1.2V5.5c0-.7-.6-1.2-1.2-1.2m63.9 29.4-3.6-.7c-.4-.1-.8.1-1 .5-1.7 2.8-4.8 4.7-8.3 4.7-3 0-5.7-1.4-7.5-3.5l17.2-7.2 5.2-2.2c-1.5-7.1-8-12.3-15.6-11.9s-13.8 6.5-14.3 14.1c-.6 8.9 6.4 16.3 15.1 16.3 6 0 11.2-3.5 13.6-8.5.2-.8-.2-1.5-.8-1.6m-22.7-5.3c0-5.4 4.4-9.7 9.7-9.7 3 0 5.8 1.4 7.5 3.6l-17.2 7.3zM332 25.2c-1.5-7.1-8-12.3-15.6-11.9s-13.8 6.5-14.3 14.1c-.6 8.9 6.4 16.3 15.1 16.3 6 0 11.2-3.5 13.7-8.6.3-.6-.1-1.3-.7-1.4l-3.6-.7c-.4-.1-.8.1-1 .5-1.7 2.8-4.8 4.7-8.3 4.7-3 0-5.7-1.4-7.5-3.5l17.2-7.2zm-24.5 4.4c0-.4-.1-.8-.1-1.2 0-5.4 4.4-9.7 9.7-9.7 3 0 5.8 1.4 7.5 3.6zM283.2.7h-3.6c-.5 0-.9.4-.9.9v40.7c0 .5.4 1 1 1h3.5c.5 0 1-.4 1-1V1.6c0-.5-.5-.9-1-.9m12.3 0h-3.6c-.5 0-.9.4-.9.9v40.7c0 .5.4 1 1 1h3.5c.5 0 1-.4 1-1V1.6c-.1-.5-.5-.9-1-.9m95.1 12.7h-3.1c-.7 0-1.2.5-1.2 1.2v27.6c0 .7.5 1.2 1.2 1.2h3.1c.7 0 1.2-.5 1.2-1.2V14.5c0-.6-.6-1.1-1.2-1.1m-10.2 0h-3.9c-.4 0-.8-.4-.8-.8V1.5c0-.4-.4-.8-.8-.8H371c-.4 0-.8.4-.8.8v11.1c0 .4-.4.8-.8.8h-3.9c-.4 0-.8.4-.8.8V18c0 .4.4.8.8.8h3.9c.4 0 .8.4.8.8v22.7c0 .6.5 1 1 1h3.4c.6 0 1-.5 1-1V19.6c0-.4.4-.8.8-.8h3.9c.4 0 .8-.4.8-.8v-3.9c.1-.4-.2-.7-.7-.7m-21.6 22.1c-.4-.4-1.1-.4-1.5 0-1.8 1.7-4.1 2.7-6.8 2.7-5.7 0-10.3-5-9.7-10.8.5-4.5 4.2-8.1 8.7-8.6 2.8-.3 5.5.7 7.4 2.4.6.5 1.5.5 2.1-.1l1.7-1.7c.6-.6.6-1.6 0-2.2-2.9-2.7-6.9-4.2-11.2-3.9-7.7.5-13.9 6.9-14.2 14.7-.3 8.6 6.6 15.6 15.2 15.6 4.1 0 7.9-1.6 10.6-4.3.4-.4.4-1.1 0-1.5zm-119.7 0c-.4-.4-1.1-.4-1.5 0-1.8 1.7-4.1 2.7-6.8 2.7-5.7 0-10.3-5-9.7-10.8.5-4.5 4.2-8.1 8.7-8.6 2.8-.3 5.5.7 7.4 2.4.6.5 1.5.5 2.1-.1l1.7-1.7c.6-.6.6-1.6 0-2.2-2.9-2.7-6.9-4.2-11.2-3.9-7.7.5-13.9 6.9-14.2 14.7-.3 8.6 6.6 15.6 15.2 15.6 4.1 0 7.9-1.6 10.6-4.3.4-.4.4-1.1 0-1.5zM424 13.7h-4.9c-.1 0-.2.1-.2.2l-8 23.5c-.1.2-.4.2-.4 0l-8-23.5c0-.1-.1-.2-.2-.2h-4.9c-.2 0-.3.2-.2.3l9.9 29.1c0 .1.1.2.2.2h6.8c.1 0 .2-.1.2-.2l9.9-29.1c.1-.1 0-.3-.2-.3"/></g></svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 800.5 203.19"><path d="M260.87 144.65h-37.4v-86.1h37.4c26.94 0 40.43 13.57 40.43 40.7-.01 30.26-13.49 45.4-40.43 45.4m-21.42-13.86h19c17.9 0 26.84-10.51 26.84-31.55 0-17.91-8.95-26.87-26.84-26.87h-19zm78.59 13.86h-16.42l36.63-86.1h17.19l37.41 86.1h-17.19l-10.86-23.48h-27.63l5.49-13.85h17.92l-14.12-32.34zm65.78-86.1h65.46v13.84h-24.73v72.26h-15.98V72.39h-24.75zm73.68 86.1h-16.42l36.63-86.1h17.19l37.41 86.1H515.1l-10.86-23.48h-27.63l5.49-13.85h17.92l-14.11-32.34zm122.82 0h-37.4v-86.1h37.4c26.96 0 40.43 13.57 40.43 40.7 0 30.26-13.47 45.4-40.43 45.4m-21.41-13.86h19c17.89 0 26.86-10.51 26.86-31.55 0-17.91-8.96-26.87-26.86-26.87h-19zm72.67-29.07c0-29.2 14.45-43.79 43.33-43.79 28.44 0 42.64 14.59 42.64 43.79 0 29.03-14.21 43.55-42.64 43.55-27.6 0-42.04-14.52-43.33-43.55m43.33 29.67c17.36 0 26.05-10.01 26.05-30.05 0-19.72-8.69-29.59-26.05-29.59-17.82 0-26.73 9.87-26.73 29.59 0 20.04 8.91 30.05 26.73 30.05m109.35-21.58v20.16q-5.535 1.44-9.9 1.44c-19.55 0-29.31-10.34-29.31-31.01 0-19.09 10.36-28.62 31.07-28.62 8.65 0 16.69 1.61 24.13 4.82V62.14c-7.44-2.8-15.89-4.21-25.34-4.21-30.97 0-46.46 14.15-46.46 42.47 0 29.9 15.22 44.87 45.67 44.87 10.47 0 19.17-1.52 26.13-4.58V95.64h-25.82l-5.4 14.16zm-625.39 34.35L142 133.04l-14.07 23.5-16.36-4.78-14.41 21.99.74 6.92 78.33-14.43-4.55-48.94zm-73.05-21.09 12.57-1.73c2.03.91 3.45 1.26 5.89 1.88 3.8.99 8.19 1.94 14.7-1.34 1.51-.75 4.67-3.64 5.94-5.28l51.49-9.34 5.25 63.57-88.21 15.9zm95.64-22.91-5.08.97L166.62.25.25 19.54l20.5 166.33 19.47-2.83c-1.55-2.22-3.98-4.91-8.11-8.35-5.74-4.76-3.71-12.86-.32-17.97 4.47-8.63 27.54-19.61 26.23-33.41-.47-5.02-1.27-11.55-5.93-16.03-.17 1.86.14 3.65.14 3.65s-1.91-2.44-2.87-5.77c-.95-1.28-1.69-1.68-2.7-3.39-.72 1.97-.62 4.26-.62 4.26s-1.56-3.7-1.82-6.82c-.93 1.4-1.16 4.05-1.16 4.05s-2.03-5.83-1.57-8.97c-.93-2.73-3.68-8.15-2.9-20.47 5.08 3.56 16.26 2.71 20.61-3.71 1.45-2.13 2.44-7.93-.72-19.36-2.03-7.33-7.05-18.25-9.01-22.4l-.23.17c1.03 3.34 3.16 10.33 3.98 13.73 2.47 10.29 3.13 13.87 1.97 18.61-.99 4.12-3.35 6.82-9.35 9.84-6 3.03-13.96-4.34-14.47-4.74-5.83-4.64-10.34-12.22-10.84-15.9-.52-4.03 2.32-6.45 3.76-9.74-2.05.59-4.34 1.63-4.34 1.63s2.73-2.83 6.1-5.27c1.4-.92 2.21-1.51 3.68-2.73-2.13-.03-3.86.02-3.86.02s3.55-1.92 7.23-3.31c-2.69-.12-5.27-.02-5.27-.02S35.75 27.1 42 24.5c4.3-1.76 8.5-1.24 10.86 2.17 3.1 4.47 6.35 6.9 13.25 8.41 4.24-1.88 5.52-2.84 10.84-4.29 4.68-5.15 8.36-5.82 8.36-5.82s-1.82 1.67-2.31 4.3c2.66-2.09 5.57-3.84 5.57-3.84s-1.13 1.39-2.18 3.6l.24.36c3.1-1.86 6.74-3.32 6.74-3.32s-1.04 1.32-2.26 3.02c2.34-.02 7.08.1 8.91.31 10.86.24 13.11-11.6 17.28-13.08 5.22-1.86 7.55-2.99 16.44 5.74 7.63 7.5 13.59 20.91 10.63 23.92-2.48 2.49-7.38-.97-12.8-7.74-2.87-3.58-5.03-7.81-6.05-13.19-.86-4.54-4.19-7.17-4.19-7.17s1.93 4.31 1.93 8.11c0 2.08.26 9.84 3.59 14.19-.33.64-.48 3.15-.85 3.63-3.87-4.68-12.19-8.03-13.54-9.02 4.59 3.76 15.14 12.4 19.19 20.68 3.83 7.83 1.57 15.01 3.51 16.87.55.53 8.24 10.11 9.72 14.93 2.58 8.39.15 17.21-3.22 22.68l-9.43 1.47c-1.38-.38-2.31-.58-3.55-1.29.68-1.21 2.04-4.22 2.05-4.84l-.53-.93c-2.94 4.16-7.85 8.2-11.94 10.52-5.35 3.03-11.51 2.56-15.52 1.32-11.39-3.51-22.16-11.21-24.75-13.23 0 0-.08 1.61.41 1.98 2.87 3.24 9.45 9.1 15.81 13.18l-13.55 1.49 6.41 49.89c-2.84.41-3.28.61-6.39 1.05-2.74-9.68-7.98-16.01-13.71-19.69-5.05-3.25-12.02-3.98-18.7-2.66l-.43.5c4.64-.48 10.12.19 15.74 3.75 5.52 3.49 9.97 12.51 11.61 17.94 2.1 6.94 3.55 14.36-2.1 22.23-4.02 5.59-15.74 8.68-25.22 2 2.53 4.07 5.95 7.4 10.55 8.02 6.84.93 13.33-.26 17.79-4.84 3.81-3.92 5.84-12.12 5.3-20.75l6.03-.87 2.18 15.49 99.88-12.03zm-60.77-42.08c-.28.64-.72 1.05-.06 3.12l.04.12.1.27.27.62c1.19 2.42 2.49 4.71 4.66 5.88.56-.09 1.15-.16 1.75-.19 2.04-.09 3.33.23 4.15.68.07-.41.09-1 .04-1.88-.16-3.07.61-8.29-5.29-11.04-2.23-1.03-5.35-.72-6.39.58.19.02.36.06.49.11 1.59.54.53 1.08.24 1.73m16.54 28.65c-.77-.43-4.39-.26-6.93.04-4.84.57-10.07 2.25-11.22 3.14-2.08 1.61-1.14 4.42.4 5.57 4.32 3.22 8.1 5.39 12.09 4.86 2.45-.32 4.61-4.2 6.14-7.73 1.06-2.42 1.06-5.03-.48-5.88M94.36 61.88c1.37-1.3-6.8-3-13.14 1.32-4.67 3.19-4.82 10.03-.35 13.9.45.38.82.66 1.16.88 1.31-.62 2.8-1.24 4.51-1.79 2.9-.94 5.3-1.43 7.28-1.68.95-1.06 2.05-2.92 1.77-6.29-.37-4.59-3.84-3.86-1.23-6.34" style="fill-rule:evenodd;clip-rule:evenodd;fill:#632ca6"/></svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 800.5 196.2"><path d="m167.2 98.4-54.9 10c-1.4 1.8-4.7 4.8-6.3 5.6-6.9 3.5-11.6 2.5-15.7 1.4-2.6-.7-4.1-1-6.3-2l-13.4 1.8 8.1 67.9 94.1-17zm-83.8 78.3-.8-7.4L98 145.9l17.4 5.1 15-25.1 18 11.9 13.7-28.7 4.9 52.2zM79.5 110c-6.8-4.4-13.8-10.6-16.9-14.1-.5-.4-.4-2.1-.4-2.1 2.8 2.2 14.3 10.4 26.4 14.1 4.3 1.3 10.9 1.8 16.6-1.4 4.4-2.5 9.6-6.8 12.7-11.2l.6 1c0 .7-1.5 3.9-2.2 5.2 1.3.8 2.3 1 3.8 1.4l10.1-1.6c3.6-5.8 6.2-15.2 3.4-24.2-1.6-5.1-9.8-15.4-10.4-15.9-2.1-2 .3-9.6-3.7-18-4.3-8.8-15.6-18-20.5-22.1 1.4 1 10.3 4.6 14.4 9.6.4-.5.6-3.2.9-3.9-3.6-4.6-3.8-12.9-3.8-15.1 0-4.1-2.1-8.7-2.1-8.7s3.6 2.8 4.5 7.7c1.1 5.7 3.4 10.3 6.5 14.1 5.8 7.2 11 10.9 13.7 8.2 3.2-3.2-3.2-17.5-11.3-25.5-9.5-9.3-12-8.1-17.5-6.1-4.4 1.5-6.8 14.2-18.4 13.9-2-.2-7-.4-9.5-.3 1.3-1.8 2.4-3.2 2.4-3.2s-3.9 1.6-7.2 3.6l-.3-.4c1.1-2.4 2.3-3.8 2.3-3.8s-3.1 1.9-5.9 4.1c.5-2.8 2.5-4.6 2.5-4.6s-3.9.7-8.9 6.2c-5.7 1.5-7 2.6-11.6 4.6-7.4-1.6-10.8-4.2-14.1-9-2.5-3.6-7-4.2-11.6-2.3-6.7 2.8-15.1 6.5-15.1 6.5s2.8-.1 5.6 0c-3.9 1.5-7.7 3.5-7.7 3.5s1.8-.1 4.1 0c-1.6 1.3-2.4 1.9-3.9 2.9C3.4 25.7.5 28.7.5 28.7s2.4-1.1 4.6-1.7c-1.5 3.5-4.6 6.1-4 10.4.5 3.9 5.3 12 11.6 17 .5.4 9 8.3 15.4 5.1s8.9-6.1 10-10.5c1.2-5.1.5-8.9-2.1-19.9-.9-3.6-3.1-11.1-4.2-14.6l.2-.2c2.1 4.4 7.4 16.1 9.6 23.9 3.4 12.2 2.3 18.4.8 20.7-4.7 6.8-16.6 7.8-22 4-.8 13.1 2.1 18.9 3.1 21.8-.5 3.3 1.7 9.6 1.7 9.6s.2-2.8 1.2-4.3c.3 3.3 1.9 7.3 1.9 7.3s-.1-2.4.7-4.5c1.1 1.8 1.9 2.2 2.9 3.6 1 3.6 3 6.2 3 6.2s-.3-1.9-.2-3.9c5 4.8 5.8 11.8 6.3 17.1 1.4 14.7-23.2 26.4-28 35.6-3.6 5.4-5.8 14.1.3 19.2 14.8 12.3 9.1 15.7 16.5 21.1 10.2 7.4 22.9 4.1 27.2-1.9 6-8.4 4.5-16.3 2.2-23.7-1.8-5.8-6.5-15.4-12.4-19.1-6-3.8-11.9-4.5-16.8-4l.5-.5c7.1-1.4 14.6-.6 20 2.8 6.1 3.9 11.7 10.7 14.6 21 3.3-.5 3.8-.7 6.8-1.1L65 111.6zm34.3-66.7c6.3 2.9 5.5 8.5 5.6 11.8.1.9 0 1.6-.1 2-.9-.5-2.2-.8-4.4-.7-.6 0-1.3.1-1.9.2-2.3-1.2-3.7-3.7-5-6.3-.1-.2-.2-.5-.3-.7 0-.1-.1-.2-.1-.3v-.1c-.7-2.2-.2-2.7.1-3.3s1.4-1.3-.2-1.8c-.1 0-.3-.1-.5-.1 1.1-1.4 4.4-1.8 6.8-.7M106 79.9c1.2-.9 6.8-2.7 12-3.4 2.7-.3 6.6-.5 7.4 0 1.6.9 1.6 3.7.5 6.3-1.6 3.8-3.9 7.9-6.6 8.2-4.3.6-8.3-1.7-12.9-5.2-1.6-1.2-2.6-4.2-.4-5.9M65.6 51.4c6.8-4.6 15.5-2.8 14-1.4-2.8 2.7.9 1.9 1.3 6.8.3 3.6-.9 5.6-1.9 6.7-2.1.3-4.7.8-7.8 1.8-1.8.6-3.4 1.2-4.8 1.9q-.6-.3-1.2-.9c-4.7-4.2-4.5-11.5.4-14.9" style="fill:#fff"/><path d="M249.2 141.8H211v-88h38.2c27.5 0 41.3 13.9 41.3 41.6 0 30.9-13.7 46.4-41.3 46.4m-21.8-14.2h19.4c18.3 0 27.4-10.7 27.4-32.2 0-18.3-9.1-27.4-27.4-27.4h-19.4zm80.2 14.2h-16.7l37.4-88h17.6l38.2 88h-17.6l-11.1-24h-28.2l5.6-14.1h18.3l-14.4-33.1zm67.2-88h66.9V68h-25.2v73.8h-16.4V68h-25.3zm75.3 88h-16.8l37.5-88h17.5l38.2 88H509l-11.1-24h-28.3l5.6-14.1h18.3l-14.4-33.1zm125.5 0h-38.2v-88h38.2c27.5 0 41.3 13.9 41.3 41.6 0 30.9-13.8 46.4-41.3 46.4m-21.9-14.2h19.4c18.3 0 27.4-10.7 27.4-32.2 0-18.3-9.2-27.4-27.4-27.4h-19.4zM628 97.9c0-29.8 14.8-44.7 44.3-44.7 29 0 43.6 14.9 43.6 44.7 0 29.7-14.5 44.5-43.6 44.5-28.3 0-43-14.8-44.3-44.5m44.2 30.3c17.7 0 26.6-10.2 26.6-30.7 0-20.2-8.9-30.2-26.6-30.2-18.2 0-27.3 10.1-27.3 30.2 0 20.5 9.1 30.7 27.3 30.7m111.7-22v20.6c-3.8 1-7.1 1.5-10.1 1.5-20 0-30-10.6-30-31.7 0-19.5 10.6-29.2 31.7-29.2 8.8 0 17 1.6 24.7 4.9V57.5c-7.6-2.9-16.2-4.3-25.9-4.3-31.6 0-47.5 14.4-47.5 43.4 0 30.6 15.5 45.8 46.7 45.8 10.7 0 19.6-1.6 26.7-4.7v-46h-26.4l-5.5 14.5z" style="fill-rule:evenodd;clip-rule:evenodd;fill:#fff"/></svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="4438" height="1000" fill="none" viewBox="0 0 4438 1000"><path fill="#000" d="M2223.75 250c-172.5 0-296.88 112.5-296.88 281.25s139.85 281.25 312.51 281.25c104.21 0 196.09-41.25 252.96-110.781l-119.53-69.063c-31.56 34.532-79.53 54.688-133.43 54.688-74.85 0-138.44-39.063-162.04-101.563h437.82c3.43-17.5 5.47-35.625 5.47-54.687C2520.63 362.5 2396.41 250 2223.75 250m-147.66 226.562C2095.62 414.219 2149.06 375 2223.75 375c74.84 0 128.28 39.219 147.66 101.562zm-35.31-398.437-432.97 750-433.12-750h162.34l270.63 468.75 270.62-468.75zM577.344 0l577.346 1000H0zM3148.75 531.25C3148.75 625 3210 687.5 3305 687.5c64.38 0 112.66-29.219 137.5-76.875l120 69.219C3512.81 762.656 3419.69 812.5 3305 812.5c-172.66 0-296.87-112.5-296.87-281.25S3132.5 250 3305 250c114.69 0 207.66 49.844 257.5 132.656l-120 69.219C3417.66 404.219 3369.38 375 3305 375c-94.84 0-156.25 62.5-156.25 156.25M4437.5 78.125v718.75h-140.62V78.125zM3906.25 250c-172.5 0-296.87 112.5-296.87 281.25s140 281.25 312.5 281.25c104.21 0 196.09-41.25 252.96-110.781l-119.53-69.063c-31.56 34.532-79.53 54.688-133.43 54.688-74.85 0-138.44-39.063-162.04-101.563h437.82c3.43-17.5 5.46-35.625 5.46-54.687C4203.12 362.5 4078.91 250 3906.25 250m-147.66 226.562C3778.13 414.219 3831.41 375 3906.25 375s128.28 39.219 147.66 101.562zm-797.34-210.937v151.406c-15.62-4.531-32.19-7.656-50-7.656-90.78 0-156.25 62.5-156.25 156.25v231.25h-140.62v-531.25H2755v143.75c0-79.375 92.34-143.75 206.25-143.75"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="4438" height="1000" fill="none" viewBox="0 0 4438 1000"><path fill="#fff" d="M2223.75 250c-172.5 0-296.88 112.5-296.88 281.25s139.85 281.25 312.51 281.25c104.21 0 196.09-41.25 252.96-110.781l-119.53-69.063c-31.56 34.532-79.53 54.688-133.43 54.688-74.85 0-138.44-39.063-162.04-101.563h437.82c3.43-17.5 5.47-35.625 5.47-54.687C2520.63 362.5 2396.41 250 2223.75 250m-147.66 226.562C2095.62 414.219 2149.06 375 2223.75 375c74.84 0 128.28 39.219 147.66 101.562zm-35.31-398.437-432.97 750-433.12-750h162.34l270.63 468.75 270.62-468.75zM577.344 0l577.346 1000H0zM3148.75 531.25C3148.75 625 3210 687.5 3305 687.5c64.38 0 112.66-29.219 137.5-76.875l120 69.219C3512.81 762.656 3419.69 812.5 3305 812.5c-172.66 0-296.87-112.5-296.87-281.25S3132.5 250 3305 250c114.69 0 207.66 49.844 257.5 132.656l-120 69.219C3417.66 404.219 3369.38 375 3305 375c-94.84 0-156.25 62.5-156.25 156.25M4437.5 78.125v718.75h-140.62V78.125zM3906.25 250c-172.5 0-296.87 112.5-296.87 281.25s140 281.25 312.5 281.25c104.21 0 196.09-41.25 252.96-110.781l-119.53-69.063c-31.56 34.532-79.53 54.688-133.43 54.688-74.85 0-138.44-39.063-162.04-101.563h437.82c3.43-17.5 5.46-35.625 5.46-54.687C4203.12 362.5 4078.91 250 3906.25 250m-147.66 226.562C3778.13 414.219 3831.41 375 3906.25 375s128.28 39.219 147.66 101.562zm-797.34-210.937v151.406c-15.62-4.531-32.19-7.656-50-7.656-90.78 0-156.25 62.5-156.25 156.25v231.25h-140.62v-531.25H2755v143.75c0-79.375 92.34-143.75 206.25-143.75"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 949 KiB

View file

@ -1,3 +0,0 @@
<svg width="4438" height="1000" viewBox="0 0 4438 1000" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2223.75 250C2051.25 250 1926.87 362.5 1926.87 531.25C1926.87 700 2066.72 812.5 2239.38 812.5C2343.59 812.5 2435.47 771.25 2492.34 701.719L2372.81 632.656C2341.25 667.188 2293.28 687.344 2239.38 687.344C2164.53 687.344 2100.94 648.281 2077.34 585.781H2515.16C2518.59 568.281 2520.63 550.156 2520.63 531.094C2520.63 362.5 2396.41 250 2223.75 250ZM2076.09 476.562C2095.62 414.219 2149.06 375 2223.75 375C2298.59 375 2352.03 414.219 2371.41 476.562H2076.09ZM2040.78 78.125L1607.81 828.125L1174.69 78.125H1337.03L1607.66 546.875L1878.28 78.125H2040.78ZM577.344 0L1154.69 1000H0L577.344 0ZM3148.75 531.25C3148.75 625 3210 687.5 3305 687.5C3369.38 687.5 3417.66 658.281 3442.5 610.625L3562.5 679.844C3512.81 762.656 3419.69 812.5 3305 812.5C3132.34 812.5 3008.13 700 3008.13 531.25C3008.13 362.5 3132.5 250 3305 250C3419.69 250 3512.66 299.844 3562.5 382.656L3442.5 451.875C3417.66 404.219 3369.38 375 3305 375C3210.16 375 3148.75 437.5 3148.75 531.25ZM4437.5 78.125V796.875H4296.88V78.125H4437.5ZM3906.25 250C3733.75 250 3609.38 362.5 3609.38 531.25C3609.38 700 3749.38 812.5 3921.88 812.5C4026.09 812.5 4117.97 771.25 4174.84 701.719L4055.31 632.656C4023.75 667.188 3975.78 687.344 3921.88 687.344C3847.03 687.344 3783.44 648.281 3759.84 585.781H4197.66C4201.09 568.281 4203.12 550.156 4203.12 531.094C4203.12 362.5 4078.91 250 3906.25 250ZM3758.59 476.562C3778.13 414.219 3831.41 375 3906.25 375C3981.09 375 4034.53 414.219 4053.91 476.562H3758.59ZM2961.25 265.625V417.031C2945.63 412.5 2929.06 409.375 2911.25 409.375C2820.47 409.375 2755 471.875 2755 565.625V796.875H2614.38V265.625H2755V409.375C2755 330 2847.34 265.625 2961.25 265.625Z" fill="black"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -1,3 +0,0 @@
<svg width="4438" height="1000" viewBox="0 0 4438 1000" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2223.75 250C2051.25 250 1926.87 362.5 1926.87 531.25C1926.87 700 2066.72 812.5 2239.38 812.5C2343.59 812.5 2435.47 771.25 2492.34 701.719L2372.81 632.656C2341.25 667.188 2293.28 687.344 2239.38 687.344C2164.53 687.344 2100.94 648.281 2077.34 585.781H2515.16C2518.59 568.281 2520.63 550.156 2520.63 531.094C2520.63 362.5 2396.41 250 2223.75 250ZM2076.09 476.562C2095.62 414.219 2149.06 375 2223.75 375C2298.59 375 2352.03 414.219 2371.41 476.562H2076.09ZM2040.78 78.125L1607.81 828.125L1174.69 78.125H1337.03L1607.66 546.875L1878.28 78.125H2040.78ZM577.344 0L1154.69 1000H0L577.344 0ZM3148.75 531.25C3148.75 625 3210 687.5 3305 687.5C3369.38 687.5 3417.66 658.281 3442.5 610.625L3562.5 679.844C3512.81 762.656 3419.69 812.5 3305 812.5C3132.34 812.5 3008.13 700 3008.13 531.25C3008.13 362.5 3132.5 250 3305 250C3419.69 250 3512.66 299.844 3562.5 382.656L3442.5 451.875C3417.66 404.219 3369.38 375 3305 375C3210.16 375 3148.75 437.5 3148.75 531.25ZM4437.5 78.125V796.875H4296.88V78.125H4437.5ZM3906.25 250C3733.75 250 3609.38 362.5 3609.38 531.25C3609.38 700 3749.38 812.5 3921.88 812.5C4026.09 812.5 4117.97 771.25 4174.84 701.719L4055.31 632.656C4023.75 667.188 3975.78 687.344 3921.88 687.344C3847.03 687.344 3783.44 648.281 3759.84 585.781H4197.66C4201.09 568.281 4203.12 550.156 4203.12 531.094C4203.12 362.5 4078.91 250 3906.25 250ZM3758.59 476.562C3778.13 414.219 3831.41 375 3906.25 375C3981.09 375 4034.53 414.219 4053.91 476.562H3758.59ZM2961.25 265.625V417.031C2945.63 412.5 2929.06 409.375 2911.25 409.375C2820.47 409.375 2755 471.875 2755 565.625V796.875H2614.38V265.625H2755V409.375C2755 330 2847.34 265.625 2961.25 265.625Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB