{"id":379,"date":"2026-02-23T20:17:34","date_gmt":"2026-02-23T20:17:34","guid":{"rendered":"https:\/\/tolva.fr\/?p=379"},"modified":"2026-02-23T20:17:34","modified_gmt":"2026-02-23T20:17:34","slug":"salsa-et-utopia","status":"publish","type":"post","link":"https:\/\/tolva.fr\/index.php\/2026\/02\/23\/salsa-et-utopia\/","title":{"rendered":"Salsa et utopia"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\"><strong>L&rsquo;application Utopia<\/strong><\/h2>\n\n\n\n<p>Utopia est une application offrant une fonctionnalit\u00e9 de messagerie instantan\u00e9e et d&rsquo;appels vocaux, mais proposant aussi des <em>boucles<\/em> comparables aux \u00e0 celles de telegram, ainsi que des services en lien avec les cryptomonnaies.<\/p>\n\n\n\n<p>C&rsquo;est \u00e0 la fonctionnalit\u00e9 de messagerie instantan\u00e9e qu&rsquo;on s&rsquo;int\u00e9resse.<\/p>\n\n\n\n<p>Un passage sur le site internet nous apprends que l&rsquo;\u00e9change de messages s&rsquo;effectue au dessus d&rsquo;un r\u00e9seau P2P. <\/p>\n\n\n\n<p>Les motivations, l&rsquo;identit\u00e9 et la nature juridique du d\u00e9veloppeur restent floues.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"455\" height=\"364\" src=\"https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/image0.png\" alt=\"\" class=\"wp-image-381\" srcset=\"https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/image0.png 455w, https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/image0-300x240.png 300w\" sizes=\"auto, (max-width: 455px) 100vw, 455px\" \/><\/figure>\n\n\n\n<p>L&rsquo;interface de l&rsquo;application propose un onglet listant les conversations :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"535\" height=\"266\" src=\"https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/image1.png\" alt=\"\" class=\"wp-image-382\" srcset=\"https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/image1.png 535w, https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/image1-300x149.png 300w\" sizes=\"auto, (max-width: 535px) 100vw, 535px\" \/><\/figure>\n\n\n\n<p>un autre onglet listant les <em>boucles<\/em> :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"455\" height=\"138\" src=\"https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/image2.png\" alt=\"\" class=\"wp-image-383\" srcset=\"https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/image2.png 455w, https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/image2-300x91.png 300w\" sizes=\"auto, (max-width: 455px) 100vw, 455px\" \/><\/figure>\n\n\n\n<p>et un dernier onglet li\u00e9 aux fonctionnalit\u00e9s crypto :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"456\" height=\"582\" src=\"https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/image3.png\" alt=\"\" class=\"wp-image-384\" srcset=\"https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/image3.png 456w, https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/image3-235x300.png 235w\" sizes=\"auto, (max-width: 456px) 100vw, 456px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Le trafic de l&rsquo;application<\/strong><\/h2>\n\n\n\n<p>On intercepte le trafic de l&rsquo;application avec tcpdump et on examine le pcap obtenu avec wireshark :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1918\" height=\"898\" src=\"https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/wireshark01.png\" alt=\"\" class=\"wp-image-386\" srcset=\"https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/wireshark01.png 1918w, https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/wireshark01-300x140.png 300w, https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/wireshark01-768x360.png 768w, https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/wireshark01-1536x719.png 1536w\" sizes=\"auto, (max-width: 1918px) 100vw, 1918px\" \/><\/figure>\n\n\n\n<p>Le trafic ne correspond \u00e0 rien de connu, en tout cas \u00e0 rien de connu de wireshark !<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u00c0 la recherche du chiffrement<\/strong><\/h2>\n\n\n\n<p>Une question naturelle est de s&rsquo;int\u00e9resser au m\u00e9canisme de chiffrement des messages. Comme il s&rsquo;agit d&rsquo;une application Android, le chiffrement peut \u00eatre r\u00e9alis\u00e9 dans le code java\/kotlin dans l&rsquo;application (comme c&rsquo;\u00e9tait le cas pour Seatalk), ou dans une biblioth\u00e8que native propre \u00e0 l&rsquo;application.<\/p>\n\n\n\n<p>Comme c&rsquo;est le chemin le plus ais\u00e9, on commence par regarder les parties non-natives de l&rsquo;application.<\/p>\n\n\n\n<p>Avec frida, et plus exactement avec frida-trace, on trace les appels \u00e0 divers packages et fonctions qui pourraient \u00eatre des bons candidats pour chiffrer les messages textes :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>les packages et fonctions usuels du JRE impliqu\u00e9s dans du chiffrement : <code>javax.crypto.*<\/code>, <code>update<\/code>, <code>updateAAD<\/code>, <code>getIV<\/code>, <code>doFinal<\/code>, <code>Cipher<\/code>, etc<\/li>\n\n\n\n<li>d&rsquo;\u00e9ventuelles fonctions dont le nom mentionne un algorithme de chiffrement usuel : AES, SHA256, SHA512, etc<\/li>\n\n\n\n<li>les packages dont le nom contient la cha\u00eene de caract\u00e8res \u00ab\u00a0message\u00a0\u00bb (comme <code>is.u.utopia.message<\/code>)<\/li>\n<\/ul>\n\n\n\n<p>Malheureusement, tout ceci ne m\u00e8ne \u00e0 rien. Une id\u00e9e naturelle est de regarder les biblioth\u00e8ques natives embarqu\u00e9es dans l&rsquo;application, qui en contient un nombre tr\u00e8s important (118 !).<\/p>\n\n\n\n<p>En les triant par taille, la plus grande est <code>libUtopia_arm64-v8a.so<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>$ ls -lhSr utopia_app\/is.u.utopia-gvdTWTlayzyirVLz5riYkQ\\=\\=\/lib\/arm64\/\ntotal 303M\n(...)\n-rw-r--r-- 1 thomas thomas 5,4M 14 janv. 21:06 libQt6Qml_arm64-v8a.so\n-rw-r--r-- 1 thomas thomas 5,9M 14 janv. 21:06 libQt6Core_arm64-v8a.so\n-rw-r--r-- 1 thomas thomas 7,0M 14 janv. 21:06 libQt6Quick_arm64-v8a.so\n-rw-r--r-- 1 thomas thomas 7,6M 14 janv. 21:06 libQt6Gui_arm64-v8a.so\n-rw-r--r-- 1 thomas thomas  13M 14 janv. 21:06 libavcodec.so\n-rw-r--r-- 1 thomas thomas  42M 14 janv. 21:06 libvlc.so\n-rw-r--r-- 1 thomas thomas 163M 14 janv. 21:06 libUtopia_arm64-v8a.so<\/code><\/pre>\n\n\n\n<p>Int\u00e9ressons-nous \u00e0 cette biblioth\u00e8que, et tra\u00e7ons certaines de ses fonctions. On suit la m\u00eame d\u00e9marche que celle utilis\u00e9e sans succ\u00e8s dans le code non-natif.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>On trace tout ce qui est en rapport avec aes\/Aes\/AES : cela ne donne rien<\/li>\n\n\n\n<li>On frida-trace les fonctions dont le nom contient \u00ab\u00a0<em>salsa<\/em>\u00a0\u00bb : Bingo !<\/li>\n<\/ul>\n\n\n\n<p>Certaine fonctions sont appel\u00e9es tr\u00e8s r\u00e9guli\u00e8rement :<\/p>\n\n\n\n<p><code>crypto_stream_salsa20_xor_ic<\/code>, <code>crypto_stream_salsa20_xor<\/code>, <code>crypto_secretbox_xsalsa20poly1305_open<\/code>, <code>crypto_secretbox_xsalsa20poly1305<\/code>, <code>crypto_box_curve25519xsalsa20poly1305_afternm<\/code>.<\/p>\n\n\n\n<p>Une petite recherche sur un moteur de recherche nous informe que ces fonctions proviennent de la biblioth\u00e8que cryptographique libsodium.<\/p>\n\n\n\n<p>Les sources de cette biblioth\u00e8que nous \u00e9clairent sur les relations qu&rsquo;entretiennent entre elles ces fonctions, informations que nous pouvons corroborer dynamiquement :<\/p>\n\n\n\n<p>Pour cela, on cr\u00e9e des scripts frida hookant ces fonctions, et l&rsquo;on ajoute un appel \u00e0 <code>Thread.backtrace(this.context, Backtracer.ACCURATE)<\/code> pour dumper la pile d&rsquo;appel dans les hooks de ces fonctions.<\/p>\n\n\n\n<p>Il ressort de tout cela que :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>crypto_stream_salsa20_xor<\/code> appelle <code>crypto_stream_salsa20_xor_ic<\/code>,<\/li>\n\n\n\n<li><code>crypto_secretbox_xsalsa20poly1305_open<\/code> appelle <code>crypto_stream_salsa20_xor<\/code>,<\/li>\n\n\n\n<li><code>crypto_box_curve25519xsalsa20poly1305_afternm<\/code> appelle <code>crypto_secretbox_xsalsa20poly1305<\/code>,<\/li>\n\n\n\n<li><code>crypto_secretbox_xsalsa20poly1305<\/code> appelle <code>crypto_stream_salsa20_xor<\/code>.<\/li>\n<\/ul>\n\n\n\n<p>Compte tenu de tout ceci, compte tenu \u00e9galement des fr\u00e9quences auxquelles ces diff\u00e9rentes fonctions sont appel\u00e9es, il semble pertinent de se concentrer sur les appels \u00e0 <code>crypto_secretbox_xsalsa20poly1305<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Chiffrement avec XSalsa20<\/strong><\/h2>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>utopia::crypto::encrypt(std::__ndk1::span&lt;unsigned char const, 18446744073709551615ul&gt;,\n                        std::__ndk1::span&lt;unsigned char const, 18446744073709551615ul&gt;,\n                        std::__ndk1::span&lt;unsigned char const, 18446744073709551615ul&gt;,\n                        utopia::utils::ByteArray&amp;,\n                        utopia::utils::ByteArray&amp;,\n                        utopia::utils::ByteArray&amp;)<\/code><\/pre>\n\n\n\n<p>et<\/p>\n\n\n\n<p><code>_ZN6utopia6crypto7encryptENSt6__ndk14spanIKhLm18446744073709551615EEES4_S4_RNS_5utils9ByteArrayE<\/code> <\/p>\n\n\n\n<p>dont la signature est :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>utopia::crypto::encrypt(std::__ndk1::span&lt;unsigned char const, 18446744073709551615ul>,\n                        std::__ndk1::span&lt;unsigned char const, 18446744073709551615ul>,\n                        std::__ndk1::span&lt;unsigned char const, 18446744073709551615ul>,\n                        utopia::utils::ByteArray&amp;)<\/code><\/pre>\n\n\n\n<p>ces deux fonctions (que nous nommerons encrypt(1, 2, 3, 4, 5, 6) et encrypt(1, 2, 3, 4)) sont appel\u00e9es par <code>utopia::PrivateMessage::sendInstantMessage(utopia::AddressInfo const&amp;, utopia::PrivateMessageInfo const&amp;)<\/code><\/p>\n\n\n\n<p>Un petit coup d&rsquo;oeil au code source de <code>crypto_secretbox_xsalsa20poly1305<\/code> dans libsodium permet de comprendre les r\u00f4les des diff\u00e9rents arguments :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>int crypto_secretbox_xsalsa20poly1305(unsigned char *c,\n                                      const unsigned char *m,\n                                      unsigned long long mlen,\n                                      const unsigned char *n,\n                                      const unsigned char *k)<\/code><\/pre>\n\n\n\n<p>Si l&rsquo;on dumpe le message (argument <code>m<\/code>) :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>crypto_secretbox_xsalsa20poly1305() (thread n\u00b025266) input:\nciphertext buffer addr:0x78792639b0\nplaintext buffer content (addr = 0x7879506640):\n           0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF\n00000000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................\n00000010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................\n00000020  73 61 6e 64 77 69 63 68 20 61 75 20 6a 61 6d 62  sandwich au jamb\n00000030  6f 6e                                            on<\/code><\/pre>\n\n\n\n<p>Sa longueur (argument <code>mlen<\/code>) :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>plaintext buffer length: 0x32<\/code><\/pre>\n\n\n\n<p>Le nonce (argument <code>n<\/code>) :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>nonce:\n           0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF\n00000000  1f bf cd 18 44 ff f1 7f 03 ba cf 24 e6 0a 7e d3  ....D......$..~.\n00000010  ba 62 c9 8d 95 c1 7c c5                          .b....|.<\/code><\/pre>\n\n\n\n<p>Et la cl\u00e9 (argument <code>k<\/code>) :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>key (addr = 0x783d892680 ):\n           0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF\n00000000  4d b8 0f 3e a4 74 12 eb ca 43 62 f9 e2 19 cd 4e  M..&gt;.t...Cb....N\n00000010  aa 8c 0b 10 5b 0d 76 27 16 ba 4c b4 64 56 71 34  ....&#91;.v'..L.dVq4<\/code><\/pre>\n\n\n\n<p>en d\u00e9but d&rsquo;ex\u00e9cution, puis le chiffr\u00e9 (argument <code>c<\/code>) en sortie :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>ciphertext addr = 0x78792639b0\nciphertext content:\n           0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF\n00000000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................\n00000010  9b a1 47 45 60 ec 93 af de c5 7b 27 08 6b 2e a4  ..GE`.....{'.k..\n00000020  37 72 6a 0b 37 d8 70 df 54 be d9 15 bc a2 4d 4b  7rj.7.p.T.....MK\n00000030  69 be 00 00 00 00 00 00 65 00 00 00 00 00 00 00  i.......e.......\n00000040  04 01 04 00 00 00 e3 aa 00 00 00 00 00 00 00 00  ................\n00000050  00 00 00 00 00 00 00 00 00 00 87 44 00 00 00 00  ...........D....\n00000060  00 00 87 44 00 00 16 45 00 00 00 00 00 00 16 45  ...D...E.......E\n00000070  e0 59                                            .Y<\/code><\/pre>\n\n\n\n<p>On peut reproduire le calcul avec un petit programme faisant appel \u00e0 libsodium :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>$ cat test.c\n#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;string.h&gt;\n\n#include &lt;sodium.h&gt;\n\nunsigned char m&#91;50] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n                       0x73, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x63, 0x68,\n                       0x20, 0x61, 0x75, 0x20, 0x6a, 0x61, 0x6d, 0x62,\n                       0x6f, 0x6e};\n\nunsigned char n&#91;24] = {0x1f, 0xbf, 0xcd, 0x18, 0x44, 0xff, 0xf1, 0x7f,\n                       0x03, 0xba, 0xcf, 0x24, 0xe6, 0x0a, 0x7e, 0xd3,\n                       0xba, 0x62, 0xc9, 0x8d, 0x95, 0xc1, 0x7c, 0xc5};\n\nunsigned char k&#91;32] = {0x4d, 0xb8, 0x0f, 0x3e, 0xa4, 0x74, 0x12, 0xeb,\n                       0xca, 0x43, 0x62, 0xf9, 0xe2, 0x19, 0xcd, 0x4e,\n                       0xaa, 0x8c, 0x0b, 0x10, 0x5b, 0x0d, 0x76, 0x27,\n                       0x16, 0xba, 0x4c, 0xb4, 0x64, 0x56, 0x71, 0x34};\n\nint main()\n{\n    unsigned char *c = malloc(256 * sizeof(unsigned char));\n    memset(c, 0x00, 256);\n\n    \/\/crypto_stream_xsalsa20_xor(c, m, 36, n, k);\n    crypto_secretbox_xsalsa20poly1305(c, m, 50, n, k);\n\n    for (int i = 0; i &lt; 64; i++)\n    {\n        printf(\"%02X \", c&#91;i]);\n        if (i &gt; 0 &amp; i % 16 == 15)\n        {\n            printf(\"\\n\");\n        }\n    }\n\n    return 0;\n}\n$ gcc test.c -o test -lsodium\n$ .\/test \n00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \n9B A1 47 45 60 EC 93 AF DE C5 7B 27 08 6B 2E A4 \n37 72 6A 0B 37 D8 70 DF 54 BE D9 15 BC A2 4D 4B \n69 BE 00 00 00 00 00 00 00 00 00 00 00 00 00 00<\/code><\/pre>\n\n\n\n<p>Si l&rsquo;on suit l&rsquo;origine du message clair, on l&rsquo;aper\u00e7oit auparavant dans la fonction appelante (la variante \u00e0 4 arguments de <code>utopia::crypto::encrypt()<\/code>), dans le premier argument :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>utopia::crypto::encrypt(1, 2, 3, 4)\nparam1 addr: 0x783d896340\nparam1 content:\n           0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF\n00000000  73 61 6e 64 77 69 63 68 20 61 75 20 6a 61 6d 62  sandwich au jamb\n00000010  6f 6e 60 c9 77 00 00 00 00 00 00 00 00 00 00 00  on`.w...........\n00000020  02 01 02 00 00 00 57 2f 00 00 00 00 00 00 00 00  ......W\/........\n00000030  02 00 00 00 00 00 00 00 90 07 aa da 77 00 00 00  ............w...\n00000040  a0 07 aa da 77 00 00 00 a0 07 aa da 77 00 00 00  ....w.......w...\n00000050  02 01 02 00 00 00 63 1f 00 00 00 00 00 00 00 00  ......c.........\n00000060  02 00 00 00 00 00 00 00 b0 fc a8 da 77 00 00 00  ............w...\n00000070  c0 fc a8 da 77 00 00 00 c0 fc a8 da 77 00 00 00  ....w.......w...\n00000080  02 81 01 00 00 00 50 a2 00 00 00 00 00 00 00 00  ......P.........\n00000090  50 a4 86 3d 78 00 00 00 60 a5 8d 3d 78 00 00 00  P..=x...`..=x...\n000000a0  10 ce 8d 3d 78 00 00 00 00 00 00 00 00 00 00 00  ...=x...........\n000000b0  02 81 01 00 00 00 d6 24 00 00 00 00 00 00 00 00  .......$........\n000000c0  a0 0b 96 3d 78 00 00 00 c0 40 56 3d 78 00 00 00  ...=x....@V=x...\n000000d0  40 c8 84 3d 78 00 00 00 00 00 00 00 00 00 00 00  @..=x...........\n000000e0  02 81 01 00 00 00 7d 67 00 00 00 00 00 00 00 00  ......}g........\n000000f0  90 fa aa 3d 78 00 00 00 e0 5e 96 3d 78 00 00 00  ...=x....^.=x...<\/code><\/pre>\n\n\n\n<p>Les deux autres arguments sont respectivement la taille du message clair, le nonce et la taille du nonce :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>param2: 0x12\nparam3 addr: 0x783d8dd620\nparam3 content:\n           0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF\n00000000  1f bf cd 18 44 ff f1 7f 03 ba cf 24 e6 0a 7e d3  ....D......$..~.\n00000010  ba 62 c9 8d 95 c1 7c c5 98 8e 9f da 77 00 00 00  .b....|.....w...\n00000020  02 01 02 00 00 00 a1 a0 00 00 00 00 00 00 00 00  ................\n00000030  02 00 00 00 00 00 00 00 90 cb c7 da 77 00 00 00  ............w...\n00000040  a0 cb c7 da 77 00 00 00 a0 cb c7 da 77 00 00 00  ....w.......w...\n00000050  02 81 01 00 00 00 69 94 00 00 00 00 00 00 00 00  ......i.........\n00000060  f0 3d 89 3d 78 00 00 00 90 7e 8a 3d 78 00 00 00  .=.=x....~.=x...\n00000070  60 d1 85 3d 78 00 00 00 00 00 00 00 00 00 00 00  `..=x...........\n00000080  02 01 02 00 00 00 3e d3 00 00 00 00 00 00 00 00  ......&gt;.........\n00000090  02 00 00 00 00 00 00 00 30 91 90 da 77 00 00 00  ........0...w...\n000000a0  40 91 90 da 77 00 00 00 40 91 90 da 77 00 00 00  @...w...@...w...\n000000b0  02 01 02 00 00 00 c3 17 00 00 00 00 00 00 00 00  ................\n000000c0  02 00 00 00 00 00 00 00 30 db 84 da 77 00 00 00  ........0...w...\n000000d0  40 db 84 da 77 00 00 00 40 db 84 da 77 00 00 00  @...w...@...w...\n000000e0  02 81 01 00 00 00 b6 c4 00 00 00 00 00 00 00 00  ................\n000000f0  e0 25 8d 3d 78 00 00 00 10 1b 8f 3d 78 00 00 00  .%.=x......=x...\nparam4: 0x18<\/code><\/pre>\n\n\n\n<p>En continuant de tirer la pelote, on trouve indirectement trace du message clair dans le 3\u00e8me argument de <code>utopia::PrivateMessage::sendInstantMessage(utopia::AddressInfo const&amp;, utopia::PrivateMessageInfo const&amp;)<\/code>, <\/p>\n\n\n\n<p>appelante de <code>utopia::crypto::encrypt(1, 2, 3, 4)<\/code>.<\/p>\n\n\n\n<p>Ce troisi\u00e8me argument pointe sur une structure :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>param 2 addr = 0x75ab0b3098, content:\n           0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF\n00000000  d0 a3 42 b9 77 00 00 00 50 f9 3f 19 79 00 00 00  ..B.w...P.?.y...\n00000010  40 99 39 ca 75 00 00 00 d0 30 0b ab 75 00 00 00  @.9.u....0..u...\n00000020  04 00 00 00 05 00 00 00 01 00 00 00 00 00 00 00  ................<\/code><\/pre>\n\n\n\n<p>Les 8 premiers octets de cette structure contiennent une adresse o\u00f9 l&rsquo;on peut trouver le message :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>param2-&gt;offset0 = 0x77b942a3d0, content:\n           0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF\n00000000  07 00 00 00 00 00 00 00 33 3f 1d b8 12 78 41 0f  ........3?...xA.\n00000010  00 f1 aa 3d 78 00 00 00 01 00 61 74 65 5f 6d 65  ...=x.....ate_me\n00000020  24 73 61 6e 64 77 69 63 68 20 61 75 20 6a 61 6d  $sandwich au jam\n00000030  62 6f 6e 00 00 00 00 00 08 74 65 78 74 00 65 73  bon......text.es\n00000040  73 61 67 65 5f 69 6e 66 6f 22 2e 22 69 64 22 20  sage_info\".\"id\" \n00000050  40 9f d8 0b 9c 01 00 00 00 00 00 00 00 00 00 00  @...............<\/code><\/pre>\n\n\n\n<p>Sch\u00e9matiquement, on a donc ceci :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"423\" height=\"386\" src=\"https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/petitdessin.png\" alt=\"\" class=\"wp-image-389\" srcset=\"https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/petitdessin.png 423w, https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/petitdessin-300x274.png 300w\" sizes=\"auto, (max-width: 423px) 100vw, 423px\" \/><\/figure>\n\n\n\n<p>Assez \u00e9trangement, la cl\u00e9 de chiffrement n&rsquo;est pas pr\u00e9sente dans les arguments de ces deux fonctions.<\/p>\n\n\n\n<p>On en retrouve toutefois trace dans les registres x4 et x9 lors de l&rsquo;appel \u00e0 <code>utopia::crypto::encrypt(1, 2, 3, 4)<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>content at x4:            0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF\n00000000  4d b8 0f 3e a4 74 12 eb ca 43 62 f9 e2 19 cd 4e  M..&gt;.t...Cb....N\n00000010  aa 8c 0b 10 5b 0d 76 27 16 ba 4c b4 64 56 71 34  ....&#91;.v'..L.dVq4\n(...)\ncontent at x9:            0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF\n00000000  4d b8 0f 3e a4 74 12 eb ca 43 62 f9 e2 19 cd 4e  M..&gt;.t...Cb....N\n00000010  aa 8c 0b 10 5b 0d 76 27 16 ba 4c b4 64 56 71 34  ....&#91;.v'..L.dVq4\n(...)\nutopia::crypto::encrypt(1, 2, 3, 4) (thread n\u00b025266) called from:<\/code><\/pre>\n\n\n\n<p>Le message chiffr\u00e9, quant \u00e0 lui, peut \u00eatre observ\u00e9 dans la sortie de <code>crypto_secretbox_xsalsa20poly1305<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>crypto_secretbox_xsalsa20poly1305() (thread n\u00b025266) output:\nplaintext addr = 0x7879506640\nplaintext content:\n           0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF\n00000000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................\n00000010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................\n00000020  73 61 6e 64 77 69 63 68 20 61 75 20 6a 61 6d 62  sandwich au jamb\n00000030  6f 6e                                            on\nciphertext addr = 0x78792639b0\nciphertext content:\n           0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF\n00000000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................\n00000010  9b a1 47 45 60 ec 93 af de c5 7b 27 08 6b 2e a4  ..GE`.....{'.k..\n00000020  37 72 6a 0b 37 d8 70 df 54 be d9 15 bc a2 4d 4b  7rj.7.p.T.....MK\n00000030  69 be 00 00 00 00 00 00 65 00 00 00 00 00 00 00  i.......e.......\n00000040  04 01 04 00 00 00 e3 aa 00 00 00 00 00 00 00 00  ................\n00000050  00 00 00 00 00 00 00 00 00 00 87 44 00 00 00 00  ...........D....\n00000060  00 00 87 44 00 00 16 45 00 00 00 00 00 00 16 45  ...D...E.......E\n00000070  e0 59                                            .Y<\/code><\/pre>\n\n\n\n<p>On le retrouve dans un appel ult\u00e9rieur \u00e0 <code>crypto_secretbox_xsalsa20poly1305<\/code>, qui n&rsquo;est pas r\u00e9alis\u00e9 par <code>utopia::crypto::encrypt(1, 2, 3, 4)<\/code><\/p>\n\n\n\n<p>mais par <code>utopia::crypto::encrypt(1, 2, 3, 4, 5, 6)<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>crypto_secretbox_xsalsa20poly1305() (call n\u00b01) called from:\n0x75cb1d2558 libUtopia_arm64-v8a.so!crypto_box_curve25519xsalsa20poly1305_afternm+0x38\n0x75cac814e4 libUtopia_arm64-v8a.so!_ZN6utopia6crypto7encryptENSt6__ndk14spanIKhLm18446744073709551615EEES4_S4_RNS_5utils9ByteArrayES7_S7_+0x240\n0x75cae69a20 libUtopia_arm64-v8a.so!_ZN6utopia3msg12CommandLevel11setUserDataERKNS_5utils9ByteArrayES5_S5_+0x13c\n0x75cae69a20 libUtopia_arm64-v8a.so!_ZN6utopia3msg12CommandLevel11setUserDataERKNS_5utils9ByteArrayES5_S5_+0x13c\n0x75ca24822c libUtopia_arm64-v8a.so!_ZN6utopia14PrivateMessage4sendERKNS_11AddressInfoEjRKNS_3msg9UserLevelE+0x354\n0x75ca2cb4f4 libUtopia_arm64-v8a.so!_ZNSt6__ndk116__variant_detail18__copy_constructorINS0_8__traitsIJhtjmN6utopia5utils9ByteArrayEEEELNS0_6_TraitE1EED2Ev+0x18\n0x75ca2cb488 libUtopia_arm64-v8a.so!_ZNSt6__ndk116__variant_detail17__copy_assignmentINS0_8__traitsIJhtjmN6utopia5utils9ByteArrayEEEELNS0_6_TraitE1EED2Ev+0x18\n0x75ca6c17b0 libUtopia_arm64-v8a.so!0x8ea97b0\n0x75ca5e3364 libUtopia_arm64-v8a.so!0x8dcb364\n0x75ca6c1664 libUtopia_arm64-v8a.so!_ZN6utopia14ProfileStorage4Priv20updatePrivateMessageERKNS_18PrivateMessageInfoENS2_5FieldE+0x44\n0x75ca3782a4 libUtopia_arm64-v8a.so!0x8b602a4\n0x75ca248dc4 libUtopia_arm64-v8a.so!_ZN6utopia14PrivateMessage18sendInstantMessageERKNS_11AddressInfoERKNS_18PrivateMessageInfoE+0x68c\n0x75ca248db0 libUtopia_arm64-v8a.so!_ZN6utopia14PrivateMessage18sendInstantMessageERKNS_11AddressInfoERKNS_18PrivateMessageInfoE+0x678\n0x75856b37b4\n0x75856e1b4c\n0x75ca2ac47c libUtopia_arm64-v8a.so!0x8a9447c\n\ncrypto_secretbox_xsalsa20poly1305() (thread n\u00b025266) input:\nciphertext buffer addr:0x77695076e0\nplaintext buffer content (addr = 0x7769518d40):\n           0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF\n00000000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................\n00000010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................\n00000020  00 31 00 00 00 04 00 00 00 03 00 32 00 00 00 18  .1.........2....\n00000030  1f bf cd 18 44 ff f1 7f 03 ba cf 24 e6 0a 7e d3  ....D......$..~.\n00000040  ba 62 c9 8d 95 c1 7c c5 10 91 00 00 00 08 0f 41  .b....|........A\n00000050  78 12 b8 1d 3f 33 10 92 00 00 00 22 9b a1 47 45  x...?3.....\"..GE\n00000060  60 ec 93 af de c5 7b 27 08 6b 2e a4 37 72 6a 0b  `.....{'.k..7rj.\n00000070  37 d8 70 df 54 be d9 15 bc a2 4d 4b 69 be 10 96  7.p.T.....MKi...<\/code><\/pre>\n\n\n\n<p>Le message est donc chiffr\u00e9 (au moins) deux fois avant d&rsquo;\u00eatre envoy\u00e9 sur le r\u00e9seau.<\/p>\n\n\n\n<p>Cela donne un petit aper\u00e7u du fonctionnement de cette application sur laquelle on pourrait passer des mois\u2026 mais int\u00e9ressons-nous plut\u00f4t au m\u00e9canisme de chiffrement utilis\u00e9, XSalsa20.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>L&rsquo;algorithme Salsa20<\/strong><\/h2>\n\n\n\n<p>L&rsquo;algorithme Salsa20 est un algorithme de chiffrement par flot cr\u00e9\u00e9 en 2005 par le cryptologue Daniel Bernstein dans le cadre du concours eSTREAM.<\/p>\n\n\n\n<p>Ce concours, ayant eu lieu entre fin 2004 et d\u00e9but 2008 visait \u00e0 \u00e9tablir un choisir un nouvel algorithme de chiffrement par flot, un peu comme le processus ayant permis de s\u00e9lectionner l&rsquo;algorithme AES.<\/p>\n\n\n\n<p>Son design est tr\u00e8s simple, puisqu&rsquo;il n&rsquo;utilise que trois op\u00e9rations, toutes sur des entiers de 32 bits :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>addition modulo 2 ^ 32<\/li>\n\n\n\n<li>rotation<\/li>\n\n\n\n<li>xor bit \u00e0 bit.<\/li>\n<\/ul>\n\n\n\n<p>\u00c0 la diff\u00e9rence de la plupart des algorithmes de chiffrement par bloc comme AES, Salsa20 n&rsquo;utilise pas de S-box, ce qui \u00e9vite certains probl\u00e8mes :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>La pr\u00e9sence d&rsquo;une S-box induit des acc\u00e8s \u00e0 des caches. Des cache-timing attacks sont alors possibles lorsque AES est utilis\u00e9 dans un contexte o\u00f9 des attaques physiques sont possibles.<\/li>\n\n\n\n<li>Lorsque l&rsquo;on veut masquer l&rsquo;algorithme utilis\u00e9 (obfuscation d&rsquo;un malware, cryptographie en boite blanche\u2026), la pr\u00e9sence d&rsquo;une S-box dans l&rsquo;ex\u00e9cutable ou dans la m\u00e9moire du processus \u00e9tudi\u00e9 trahit l&rsquo;algorithme utilis\u00e9.<\/li>\n<\/ul>\n\n\n\n<p>Comme tout algorithme de chiffrement par flot, Salsa20 produit une suite de bits (on parle de \u00ab\u00a0keystream\u00a0\u00bb) xor\u00e9s avec les bits de clair. Le keystream est produit en en \u00ab\u00a0touillant\u00a0\u00bb un \u00e9tat interne.<\/p>\n\n\n\n<p>Salsa20 utilise un \u00e9tat interne qui prend la forme d&rsquo;une matrice 4 x 4 d&rsquo;entiers de 32 bits.<\/p>\n\n\n\n<p>L&rsquo;\u00e9tat initial de cette matrice est constitu\u00e9 \u00e0 partir de la cl\u00e9 de 256 bits, du nonce de 64 bits, d&rsquo;un index de 64 bits et d&rsquo;une suite de caract\u00e8res fixe de 128 bits :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"484\" height=\"462\" src=\"https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/salsa20_initial_state.png\" alt=\"\" class=\"wp-image-390\" srcset=\"https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/salsa20_initial_state.png 484w, https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/salsa20_initial_state-300x286.png 300w\" sizes=\"auto, (max-width: 484px) 100vw, 484px\" \/><\/figure>\n\n\n\n<p>L&rsquo;\u00e9tat interne de Salsa20 est produit en appliquant des transformations \u00e0 cet \u00e9tat initial.<\/p>\n\n\n\n<p>Ces transformations repose sur la transformation \u00e9l\u00e9mentaire suivante :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"650\" height=\"718\" src=\"https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/salsa20round.png\" alt=\"\" class=\"wp-image-391\" srcset=\"https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/salsa20round.png 650w, https:\/\/tolva.fr\/wp-content\/uploads\/2026\/02\/salsa20round-272x300.png 272w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/figure>\n\n\n\n<p>Le code de cette transformation ressemble \u00e0 ceci :<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>#define ROTL32(a, b)    (((a) &lt;&lt; (b)) | ((a) >> (32 - (b))))\n\n#define QROUND(a, b, c, d)\n{\n    a += b; d ^= a; d = ROTL32(d, 16);\n    c += d; b ^= c; b = ROTL32(b, 12);\n    a += b; d ^= a; d = ROTL32(d,  8);\n    c += d; b ^= c; b = ROTL32(b,  7);\n}<\/code><\/pre>\n\n\n\n<p>Les tours pairs mettent \u00e0 jours les lignes de l&rsquo;\u00e9tat :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>QROUND(0,   1,  2,  3);\nQROUND(5,   6,  7,  4);\nQROUND(10, 11,  8,  9);\nQROUND(15, 12, 13, 14);<\/code><\/pre>\n\n\n\n<p>ALors que les tours impairs mettent \u00e0 jour les colonnes de l&rsquo;\u00e9tat :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>QROUND(0,   4,   8,  12);\nQROUND(5,   9,  13,   1);\nQROUND(10, 14,   2,   6);\nQROUND(15,  3,   7,  11);<\/code><\/pre>\n\n\n\n<p>Salsa20 effectue 20 tours pour transformer son \u00e9tat interne.<\/p>\n\n\n\n<p>Apr\u00e8s cette derni\u00e8re \u00e9tape, l&rsquo;\u00e9tat interne transform\u00e9 est xor\u00e9 avec une sauvegarde de l&rsquo;\u00e9tat interne pour produire les bits de keystream :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>X = Y\n\nfor (i = 0; i &lt; 10; i++)\n{\n    Y  =  ODD_ROUND_TRANSFORM(Y);\n    Y  = EVEN_ROUND_TRANSFORM(Y);\n}\n\nfor (i = 0; i &lt; 16; i++)\n{\n    OUT&#91;i] ^= X&#91;i];\n}<\/code><\/pre>\n\n\n\n<p>\u00c0 l&rsquo;heure actuelle (fin f\u00e9vrier 2026), les meilleures cryptanalyses de Salsa20 portent sur des variantes affaiblies \u00e0 5, 6, 7 ou 8 tours et sont irr\u00e9alisables en pratique.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>XSalsa20<\/strong><\/h3>\n\n\n\n<p>XSalsa20 est une variante de Salsa20 utilisant un nonce de 192 bits au lieu de 64.<\/p>\n\n\n\n<p>XSalsa20 est identique \u00e0 Salsa20, modulo une \u00e9tape pr\u00e9liminaire charg\u00e9e de \u00ab\u00a0dig\u00e9rer\u00a0\u00bb les 128 premiers bits de nonce.<\/p>\n\n\n\n<p>Cette \u00e9tape se d\u00e9roule ainsi :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>construction d&rsquo;un \u00e9tat de 4 x 4 mots de 32 bits. Les 4 mots diagonaux d&rsquo;indice 0, 5, 10 et 15 sont les constantes de Salsa20 (\u00ab\u00a0expa\u00a0\u00bb, \u00ab\u00a0nd 3\u00a0\u00bb, \u00ab\u00a02-by\u00a0\u00bb et \u00ab\u00a0te k\u00a0\u00bb).<\/li>\n\n\n\n<li>les mots d&rsquo;indice 6, 7, 8 et 9 sont les 128 premiers bits du nonce<\/li>\n\n\n\n<li>les 256 autres bits sont remplis avec la clef.<\/li>\n<\/ul>\n\n\n\n<p>Cet \u00e9tat initial est mis \u00e0 jour avec HSalsa20, qui est identique \u00e0 Salsa20, except\u00e9 l&rsquo;\u00e9tape de finale xor :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>X = Y\nfor (i = 0; i &lt; 10; i++)\n{\n    Y  =  ODD_ROUND_TRANSFORM(Y);\n    Y  = EVEN_ROUND_TRANSFORM(Y);\n}<\/code><\/pre>\n\n\n\n<p>L&rsquo;\u00e9tat r\u00e9sultant Y = (y0,\u2026y15) de HSalsa20 est utilis\u00e9 avec les 64 bits restantes de nonce et les 64 bits d&rsquo;index pour initialiser un nouvel \u00e9tat initial :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>+--------+--------+--------+--------+\n| \"expa\" |   y0   |   y5   |   y10  |\n+--------+--------+--------+--------+\n|   y15  | \"nd 3\" |   n4   |    n5  |\n+--------+--------+--------+--------+\n|    c1  |    c2  | \"2-by\" |    y6  |\n+--------+--------+--------+--------+\n|    y7  |    y8  |   y9   | \"te k\" |\n+--------+--------+--------+--------+<\/code><\/pre>\n\n\n\n<p>o\u00f9 (n4, n5) sont les 64 derniers bits de nonce et (c1, c2) les 64 bits d&rsquo;index.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Chacha20<\/strong><\/h3>\n\n\n\n<p>Chacha20 est une variante de Salsa20 cr\u00e9\u00e9e en 2008 par le concepteur de Salsa20. Il partage de nombreux points communs avec Salsa20 : \u00c9tat initial de 512 bits form\u00e9 de 256 bits de cl\u00e9, de 64 bits de nonce, de 128 bits de constante et de 64 bits d&rsquo;index, mise \u00e0 jour de l&rsquo;\u00e9tat interne avec une fonction constitu\u00e9e de 20 tours.<\/p>\n\n\n\n<p>Cependant, la fonction <code>QROUND<\/code> diff\u00e8re de celle de Salsa20, et les tours impairs ne mettent pas \u00e0 jour les 4 lignes, mais les 4 diagonales de l&rsquo;\u00e9tat interne.<\/p>\n\n\n\n<p>Chacha20 est largement utilis\u00e9 puisqu&rsquo;il est l&rsquo;algorithme de chiffrement d&rsquo;une des cinq cipher_suites de TLSv1.3 (la suite <code>TLS_CHACHA20_POLY1305_SHA256<\/code>, les quatre autres utilisant AES).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>L&rsquo;algorithme Poly1305<\/strong><\/h2>\n\n\n\n<p>Poly1305 est un algorithme de mac invent\u00e9 par Daniel Bernstein (encore lui !) en 2002. L&rsquo;algorithme est aussi simple qu&rsquo;\u00e9l\u00e9gant, puisqu&rsquo;il consiste \u00e0 cr\u00e9er un constituer un polyn\u00f4me \u00e0 partir du message \u00e0 authentifier, et d&rsquo;\u00e9valuer ce polyn\u00f4me sur la clef.<\/p>\n\n\n\n<p>Rentrons un peu dans les d\u00e9tails : Supposons que l&rsquo;on souhaite authentifier un message m avec une cl\u00e9 de 256 bits, que l&rsquo;on coupe en 2 moiti\u00e9s, r et s.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>On d\u00e9coupe le message en q blocs de 16 octets,<\/li>\n\n\n\n<li>On interpr\u00e8te chacun de ces q blocs comme un entier en little-endian auquel on rajoute 2^128 (ou 2^l si le bloc ne comporte que l octets non nuls)<\/li>\n\n\n\n<li>On interpr\u00e8te ces q blocs comme les coefficients d&rsquo;un polyn\u00f4me de degr\u00e9 q ayant un coefficient constant nul<\/li>\n\n\n\n<li>On \u00e9value ce polyn\u00f4me en r et l&rsquo;on prend le reste modulo le nombre premier 2 ^ 130 &#8211; 5 (cela explique le nom Poly1305 !)<\/li>\n\n\n\n<li>On additionne le tout avec s modulo 2 ^ 128<\/li>\n<\/ul>\n\n\n\n<p>Et c&rsquo;est tout !<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>L&rsquo;application Utopia Utopia est une application offrant une fonctionnalit\u00e9 de messagerie instantan\u00e9e et d&rsquo;appels vocaux, mais proposant aussi des boucles comparables aux \u00e0 celles de telegram, ainsi que des services en lien avec les cryptomonnaies. C&rsquo;est \u00e0 la fonctionnalit\u00e9 de messagerie instantan\u00e9e qu&rsquo;on s&rsquo;int\u00e9resse. Un passage sur le site internet nous apprends que l&rsquo;\u00e9change de [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-379","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/tolva.fr\/index.php\/wp-json\/wp\/v2\/posts\/379","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tolva.fr\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tolva.fr\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tolva.fr\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tolva.fr\/index.php\/wp-json\/wp\/v2\/comments?post=379"}],"version-history":[{"count":10,"href":"https:\/\/tolva.fr\/index.php\/wp-json\/wp\/v2\/posts\/379\/revisions"}],"predecessor-version":[{"id":398,"href":"https:\/\/tolva.fr\/index.php\/wp-json\/wp\/v2\/posts\/379\/revisions\/398"}],"wp:attachment":[{"href":"https:\/\/tolva.fr\/index.php\/wp-json\/wp\/v2\/media?parent=379"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tolva.fr\/index.php\/wp-json\/wp\/v2\/categories?post=379"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tolva.fr\/index.php\/wp-json\/wp\/v2\/tags?post=379"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}