# Verify blocks signatures with Silkaj/DuniterPy

**URL:** https://forum.duniter.org/t/verify-blocks-signatures-with-silkaj-duniterpy/6635
**Category:** Silkaj
**Tags:** block, duniterpy, blockchain, silkaj
**Created:** [4 December 2019 12:40 UTC](https://forum.duniter.org/t/verify-blocks-signatures-with-silkaj-duniterpy/6635 "2019-12-04T12:40:58Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![Moul](https://forum.duniter.org/user_avatar/forum.duniter.org/moul/32/9145_2.png) [@Moul](https://forum.duniter.org/u/Moul)
#### Post date: [4 December 2019 12:40 UTC](https://forum.duniter.org/t/verify-blocks-signatures-with-silkaj-duniterpy/6635/1 "2019-12-04T12:40:58Z")

</div>

Sous-section de :

> [@Duniter utilise une ancienne version buggée de TweetNaCl: que faire?](https://forum.duniter.org/t/duniter-utilise-une-ancienne-version-buggee-de-tweetnacl-que-faire/6633):
>
> Certains o…

À lancer avec `apython`, et [`aioconsole`](https://pypi.org/project/aioconsole/) d’installé, pour avoir de l’asynchrone en console :

```python
from duniterpy.api import bma
from duniterpy.api.client import Client
from duniterpy.documents import Block
from duniterpy.key.verifying_key import VerifyingKey

client = Client("BMAS g1.duniter.org 443")
received_block = await client(bma.blockchain.block, 15144)
block = Block.from_signed_raw(received_block["raw"] + received_block["signature"] + "\n")
key = VerifyingKey(block.issuer)
key.verify_document(block)
False                            

```

Signature du bloc 15144 invalide. Pareil avec la “bonne” signature :

```python
good_signature = "aZusVDRJA8akPse/sv4uK8ekUuvTGj1OoKYVdMQQ/3+VMaDJ02I795GBBaLgjypZFEKYlPMssJMn/X+F/pxgAw=="
block = Block.from_signed_raw(received_block["raw"] + good_signature + "\n")

```

* * *

Également invalide pour les blocs suivant 1514{5,6} :

```python
received_block = await client(bma.blockchain.block, 15145)
block = Block.from_signed_raw(received_block["raw"] + received_block["signature"] + "\n")
key = VerifyingKey(block.issuer)
key.verify_document(block)
False
ValueError: Failed to validate message

```

Je sais pas quel est le problème côté DuniterPy. Le code utilisé :

- [blocks.py](https://git.duniter.org/clients/python/duniterpy/blob/dev/duniterpy/documents/block.py)
- [documents.py](https://git.duniter.org/clients/python/duniterpy/blob/dev/duniterpy/documents/document.py)
- [verifying\_key.py](https://git.duniter.org/clients/python/duniterpy/blob/dev/duniterpy/key/verifying_key.py#L22-44)
- [libnacl.sign.Verifier](https://libnacl.readthedocs.io/en/latest/topics/sign.html):

---

<div class="post-metadata">

### Author: ![elois](https://forum.duniter.org/user_avatar/forum.duniter.org/elois/32/1541_2.png) [@elois](https://forum.duniter.org/u/elois)
#### Post date: [4 December 2019 13:13 UTC](https://forum.duniter.org/t/verify-blocks-signatures-with-silkaj-duniterpy/6635/2 "2019-12-04T13:13:31Z")

</div>

@Moul il n’y a pas de saut de ligne final après la signature 😉

---

<div class="post-metadata">

### Author: ![Moul](https://forum.duniter.org/user_avatar/forum.duniter.org/moul/32/9145_2.png) [@Moul](https://forum.duniter.org/u/Moul)
#### Post date: [4 December 2019 13:17 UTC](https://forum.duniter.org/t/verify-blocks-signatures-with-silkaj-duniterpy/6635/3 "2019-12-04T13:17:20Z")

</div>

C’est comme ça qu’est implémenté le parsing de bloc dans DuniterPy. Par exemple dans Sakia :

```bash
grep -rn "Block\.from_signed_raw"
src/sakia/data/processors/blockchain.py:202: block_doc = Block.from_signed_raw("{0}{1}\n".format(block['raw'], block['signature']))
src/sakia/services/transactions.py:136: block = Block.from_signed_raw(block_data["raw"] + block_data["signature"] + "\n")

```

Sinon, ça fait une erreur de ce genre :

```python
>>> block = Block.from_signed_raw(received_block["raw"] + "aZusVDRJA8akPse/sv4uK8ekUuvTGj1OoKYVdMQQ/3+VMaDJ02I795GBBaLgjypZFEKYlPMssJ
Mn/X+F/pxgAw==")                                                                                                                     
Traceback (most recent call last):
  File "/home/moul/duniterpy/duniterpy/documents/document.py", line 68, in parse_field
    raise AttributeError
AttributeError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/moul/.local/lib/python3.7/site-packages/aioconsole/execute.py", line 95, in aexec
    result, new_local = yield from coro
  File "<aexec>", line 2, in __corofn
  File "/home/moul/duniterpy/duniterpy/documents/block.py", line 405, in from_signed_raw                                             
    signature = Block.parse_field("Signature", lines[n])                                                                             
  File "/home/moul/duniterpy/duniterpy/documents/document.py", line 71, in parse_field                                               
    raise MalformedDocumentError(field_name)                                                                                         
duniterpy.documents.document.MalformedDocumentError: Could not parse field Signature                                                 

```

Il y a un [ticket à ce sujet](https://git.duniter.org/clients/python/duniterpy/issues/110).

---

<div class="post-metadata">

### Author: ![elois](https://forum.duniter.org/user_avatar/forum.duniter.org/elois/32/1541_2.png) [@elois](https://forum.duniter.org/u/elois)
#### Post date: [4 December 2019 13:22 UTC](https://forum.duniter.org/t/verify-blocks-signatures-with-silkaj-duniterpy/6635/4 "2019-12-04T13:22:48Z")

</div>

Arf c’est peut-être l’occasion de découvrir dans la foulée un bug dans duniterpy 😅

---

<div class="post-metadata">

### Author: ![Moul](https://forum.duniter.org/user_avatar/forum.duniter.org/moul/32/9145_2.png) [@Moul](https://forum.duniter.org/u/Moul)
#### Post date: [4 December 2019 13:44 UTC](https://forum.duniter.org/t/verify-blocks-signatures-with-silkaj-duniterpy/6635/5 "2019-12-04T13:44:30Z")

</div>

Possible 🙂  
Il est aussi possible que je ne l’utilise pas correctement.  
Autrement, ça ne m’étonnerait pas de découvrir à nouveau des bugs. J’en ai trouvé pas mal depuis que je l’utilise.

Bon, c’est utilisé à un [seul endroit dans Sakia](https://git.duniter.org/clients/python/sakia/blob/1de71a18ec635ca63cf4784e4284eea7f6c1c8a1/src/sakia/services/network.py#L224-226) :

```python
    def handle_new_node(self, peer):
        key = VerifyingKey(peer.pubkey)
        if key.verify_document(peer):

```

Du coup, il me semble que je l’utilise correctement par rapport à ce code.

---

<div class="post-metadata">

### Author: ![elois](https://forum.duniter.org/user_avatar/forum.duniter.org/elois/32/1541_2.png) [@elois](https://forum.duniter.org/u/elois)
#### Post date: [4 December 2019 14:18 UTC](https://forum.duniter.org/t/verify-blocks-signatures-with-silkaj-duniterpy/6635/6 "2019-12-04T14:18:08Z")

</div>

> [@Duniter utilise une ancienne version buggée de TweetNaCl: que faire?](https://forum.duniter.org/t/duniter-utilise-une-ancienne-version-buggee-de-tweetnacl-que-faire/6633/7):
>
> key.verify\_document(block)

@Moul @vit je viens de vérifier le code et duniterpy ne sais vérifier que les documents utilisateurs + la fiche de peer, il ne sais pas vérifier le document bloc car ce dernier a une particularité : c’est le seul document dont on ne signe pas le format raw mais la partie `InnerHash: BC.FE\nNonce: 012..348\n` (le format raw sert justement a obtenir le inner hash)

Pour tester coté Duniterpy sans avoir de dev a faire, il vous suffit de rédiger un TU qui appelle directement la méthode verify de l’objet `libnacl.sign.Verifier`

[https://git.duniter.org/clients/python/duniterpy/blob/dev/duniterpy/key/verifying\_key.py#L30-37](https://git.duniter.org/clients/python/duniterpy/blob/dev/duniterpy/key/verifying_key.py#L30-37)

---

<div class="post-metadata">

### Author: ![Moul](https://forum.duniter.org/user_avatar/forum.duniter.org/moul/32/9145_2.png) [@Moul](https://forum.duniter.org/u/Moul)
#### Post date: [4 December 2019 15:14 UTC](https://forum.duniter.org/t/verify-blocks-signatures-with-silkaj-duniterpy/6635/7 "2019-12-04T15:14:50Z")

</div>

J’ai remplacé [cette ligne](https://git.duniter.org/clients/python/duniterpy/blob/dev/duniterpy/key/verifying_key.py#L37) par :

```auto
#prepended = signature + bytes(document.raw(), "ascii")
prepended = signature + bytes("InnerHash: {0}\nNonce: {1}\n".format(document.inner_hash, document.nonce), "ascii")

```

et je n’y arrive toujours pas avec la bonne signature ainsi qu’avec un autre bloc.

---

<div class="post-metadata">

### Author: ![elois](https://forum.duniter.org/user_avatar/forum.duniter.org/elois/32/1541_2.png) [@elois](https://forum.duniter.org/u/elois)
#### Post date: [4 December 2019 16:07 UTC](https://forum.duniter.org/t/verify-blocks-signatures-with-silkaj-duniterpy/6635/8 "2019-12-04T16:07:12Z")

</div>

> [@Moul](#):
>
> ```auto
> prepended = signature + bytes("InnerHash: {0}\n Nonce: {1}\n".format(document.inner_hash, document.nonce), "ascii")
> 
> ```

@Moul forcément ça ne peut pas fonctionner tu a rajouté un espace devant Nonce, j’ai pourtant pris soin de ne pas insérer cet espace dans mes précédents post 😉

---

<div class="post-metadata">

### Author: ![Moul](https://forum.duniter.org/user_avatar/forum.duniter.org/moul/32/9145_2.png) [@Moul](https://forum.duniter.org/u/Moul)
#### Post date: [4 December 2019 16:12 UTC](https://forum.duniter.org/t/verify-blocks-signatures-with-silkaj-duniterpy/6635/9 "2019-12-04T16:12:50Z")

</div>

Ok, top ! Merci pour la typo.  
Du coup le bloc #15144 a une signature valide avec la bonne signature que t’as donné plus haut et a une signature invalide avec la signature présente dans le bloc.  
Et, sur le bloc #15145, ça passe nickel !

---

<div class="post-metadata">

### Author: ![vit](https://forum.duniter.org/user_avatar/forum.duniter.org/vit/32/2775_2.png) [@vit](https://forum.duniter.org/u/vit)
#### Post date: [4 December 2019 17:44 UTC](https://forum.duniter.org/t/verify-blocks-signatures-with-silkaj-duniterpy/6635/10 "2019-12-04T17:44:48Z")

</div>

Bon ben @moul a été plus rapide que moi ! 😊

Tout est bien qui finit bien pour Duniterpy, ça me rassure.

[EDIT]  
Un ticket vient d’être créé :

> **[Handle block signature verification (#113) · Issues · clients / python /...](https://git.duniter.org/clients/python/duniterpy/-/issues/113)**
>
> DuniterPy correctly check the signature of the user (tx, wot) and the peer documents. The signature of this document is based on its raw format. Excepted the block...

---

<div class="post-metadata">

### Author: ![Moul](https://forum.duniter.org/user_avatar/forum.duniter.org/moul/32/9145_2.png) [@Moul](https://forum.duniter.org/u/Moul)
#### Post date: [13 February 2020 08:16 UTC](https://forum.duniter.org/t/verify-blocks-signatures-with-silkaj-duniterpy/6635/11 "2020-02-13T08:16:20Z")

</div>

De même pour ce post : discussion rendue publique pour raison d’archivage.  
La commande `verify` de Silkaj permet de vérifier la validité des blocs.

---

<div class="post-metadata">

### Author: ![elois](https://forum.duniter.org/user_avatar/forum.duniter.org/elois/32/1541_2.png) [@elois](https://forum.duniter.org/u/elois)
#### Post date: [29 March 2020 00:08 UTC](https://forum.duniter.org/t/verify-blocks-signatures-with-silkaj-duniterpy/6635/12 "2020-03-29T00:08:57Z")

</div>

@Moul @vit, maintenant que nous somme passé au protocole v12 sur la G1, l’un de vous peut-il fournir la liste définitive des blocs invalides sur la blockchain G1 ? (Et aussi refournir la liste pour la G1-test, je crois que Moul l’avais posté, mais je ne sais plus dans quel sujet.)

---

<div class="post-metadata">

### Author: ![Moul](https://forum.duniter.org/user_avatar/forum.duniter.org/moul/32/9145_2.png) [@Moul](https://forum.duniter.org/u/Moul)
#### Post date: [29 March 2020 08:33 UTC](https://forum.duniter.org/t/verify-blocks-signatures-with-silkaj-duniterpy/6635/13 "2020-03-29T08:33:13Z")

</div>

Bonne nouvelle, ça n’a pas changé ~depuis~ qu’on s’est attaqué au problème :

> [@Duniter utilise une ancienne version buggée de TweetNaCl: que faire?](https://forum.duniter.org/t/duniter-utilise-une-ancienne-version-buggee-de-tweetnacl-que-faire/6633/24):
>
> ```auto
> [15144, 31202, 85448, 87566, 90830, 109327, 189835, 199172, 221274, 253582]
> 
> ```
> 
> Ça offre une nouvelle commande à Silkaj : `verify` . La vérification a été plutôt rapide sur un cœur.
> 
> Même punition sur ĞTest :
> 
> ```auto
> [24316, 62067, 62551, 93288, 173118, 183706, 196196, 246027, 247211, 263207, 307038, 328741, 335914, 377316, 395714, 396024, 407913, 422366, 496751]
> 
> ```

```auto
silkaj verify
Processing blocks verification [####################################] 100%          
Within 0-309400 range, blocks with a wrong signature: 15144 31202 85448 87566 90830 109327 189835 199172 221274 253582

```

```auto
silkaj -gt verify
Processing blocks verification [####################################] 100%          
Within 0-540714 range, blocks with a wrong signature: 24316 62067 62551 93288 173118 183706 196196 246027 247211 263207 307038 328741 335914 377316 395714 396024 407913 422366 496751

```

* * *

Ça rend la commande `verify` obsolète avant même qu’elle ne soit sortie. Bon, elle apporte une bonne expérience au projet en termes de test ainsi qu’une base de code pour télécharger toute la chaîne et y faire de potentielles autres études et analyses de la chaîne de blocs en masse.
