From 5fd90d84b40469e6b8cf511c54926cd435b4e384 Mon Sep 17 00:00:00 2001
From: inso <insomniak.fr@gmaiL.com>
Date: Wed, 4 May 2016 07:12:48 +0200
Subject: [PATCH] Verifying Key

---
 docs/index.rst                  |  2 +-
 duniterpy/documents/document.py |  6 ++++++
 duniterpy/key/__init__.py       |  3 ++-
 duniterpy/key/base58.py         | 10 ++++++++++
 duniterpy/key/signing_key.py    | 12 +----------
 duniterpy/key/verifying_key.py  | 35 +++++++++++++++++++++++++++++++++
 setup.py                        |  4 ++--
 tests/key/__init__.py           |  0
 tests/key/test_verifying_key.py | 25 +++++++++++++++++++++++
 9 files changed, 82 insertions(+), 15 deletions(-)
 create mode 100644 duniterpy/key/base58.py
 create mode 100644 duniterpy/key/verifying_key.py
 create mode 100644 tests/key/__init__.py
 create mode 100644 tests/key/test_verifying_key.py

diff --git a/docs/index.rst b/docs/index.rst
index f2bf96f1..524cf6e4 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -22,7 +22,7 @@ Simply type::
 Source code
 -----------
 
-Sources can be found at https://github.com/duniter-io/duniter-python-api
+Sources can be found at https://github.com/duniter/duniter-python-api
 
 Contributions are welcome.
 
diff --git a/duniterpy/documents/document.py b/duniterpy/documents/document.py
index e809b948..bced25b4 100644
--- a/duniterpy/documents/document.py
+++ b/duniterpy/documents/document.py
@@ -59,6 +59,12 @@ class Document:
             logging.debug("Signature : \n{0}".format(signing.decode("ascii")))
             self.signatures.append(signing.decode("ascii"))
 
+    def raw(self):
+        """
+        Returns the raw document in string format
+        """
+        raise NotImplementedError()
+
     def signed_raw(self):
         """
         If keys are None, returns the raw + current signatures
diff --git a/duniterpy/key/__init__.py b/duniterpy/key/__init__.py
index dc1b0fae..66d1aa86 100644
--- a/duniterpy/key/__init__.py
+++ b/duniterpy/key/__init__.py
@@ -1 +1,2 @@
-from .signing_key import SigningKey
\ No newline at end of file
+from .signing_key import SigningKey
+from .verifying_key import VerifyingKey
\ No newline at end of file
diff --git a/duniterpy/key/base58.py b/duniterpy/key/base58.py
new file mode 100644
index 00000000..5bcb8060
--- /dev/null
+++ b/duniterpy/key/base58.py
@@ -0,0 +1,10 @@
+import base58
+
+class Base58Encoder(object):
+    @staticmethod
+    def encode(data):
+        return base58.b58encode(data)
+
+    @staticmethod
+    def decode(data):
+        return base58.b58decode(data)
\ No newline at end of file
diff --git a/duniterpy/key/signing_key.py b/duniterpy/key/signing_key.py
index 7cd1b6e1..4b646769 100644
--- a/duniterpy/key/signing_key.py
+++ b/duniterpy/key/signing_key.py
@@ -4,10 +4,9 @@ duniter public and private keys
 @author: inso
 """
 
-import base58
-import base64
 import libnacl.sign
 from pylibscrypt import scrypt
+from .base58 import Base58Encoder
 
 
 SEED_LENGTH = 32  # Length of the key
@@ -35,12 +34,3 @@ class SigningKey(libnacl.sign.Signer):
 
         super().__init__(seed)
         self.pubkey = Base58Encoder.encode(self.vk)
-
-class Base58Encoder(object):
-    @staticmethod
-    def encode(data):
-        return base58.b58encode(data)
-
-    @staticmethod
-    def decode(data):
-        return base58.b58decode(data)
diff --git a/duniterpy/key/verifying_key.py b/duniterpy/key/verifying_key.py
new file mode 100644
index 00000000..4af608d2
--- /dev/null
+++ b/duniterpy/key/verifying_key.py
@@ -0,0 +1,35 @@
+"""
+duniter public and private keys
+
+@author: inso
+"""
+
+import base58
+import base64
+import libnacl.sign
+from pylibscrypt import scrypt
+from .base58 import Base58Encoder
+
+
+class VerifyingKey(libnacl.sign.Verifier):
+    """
+    Class to verify documents
+    """
+    def __init__(self, pubkey):
+        """
+        Creates a Verify class from base58 pubkey
+        :param pubkey:
+        """
+        key = libnacl.encode.hex_encode(Base58Encoder.decode(pubkey))
+        super().__init__(key)
+
+    def verify_document(self, document, **kwargs):
+        """
+        Check specified document
+        :param duniterpy.documents.Document document:
+        :return:
+        """
+        signature = base64.b64decode(document.signatures[0])
+        prepended = signature + bytes(document.raw(**kwargs), 'ascii')
+
+        return self.verify(prepended)
diff --git a/setup.py b/setup.py
index 4b7f4b67..0c72f9f4 100644
--- a/setup.py
+++ b/setup.py
@@ -49,13 +49,13 @@ setup(
 
     author_email="insomniak.fr@gmail.com",
 
-    description="A python implementation of [duniter](https://github.com/duniter-io/duniter) API",
+    description="A python implementation of [duniter](https://github.com/duniter/duniter) API",
 
     long_description=open('README.md').read(),
 
     # Active la prise en compte du fichier MANIFEST.in
     include_package_data=True,
-    url='https://github.com/duniter-io/duniter-python-api',
+    url='https://github.com/duniter/duniter-python-api',
     test_suite="tests",
 
     classifiers=[
diff --git a/tests/key/__init__.py b/tests/key/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/tests/key/test_verifying_key.py b/tests/key/test_verifying_key.py
new file mode 100644
index 00000000..4f282725
--- /dev/null
+++ b/tests/key/test_verifying_key.py
@@ -0,0 +1,25 @@
+from duniterpy.key import VerifyingKey, SigningKey
+from duniterpy.documents import Peer
+import unittest
+
+
+class Test_VerifyingKey(unittest.TestCase):
+    def test_from_sign_to_verify(self):
+        sign_key = SigningKey("saltsalt", "passwordpassword")
+        verify_key = VerifyingKey(sign_key.pubkey)
+        self.assertEqual(verify_key.vk, sign_key.vk)
+
+    def test_peer_signature(self):
+        signed_raw = """Version: 2
+Type: Peer
+Currency: test_net
+PublicKey: 8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU
+Block: 2086-00005D6FC6E22FB308D8815A565A01C66FFB7DC761D616DE0698F6322565F1D6
+Endpoints:
+BASIC_MERKLED_API testnet.duniter.inso.ovh 80
+4aQ/sfqFAFUeYkkLdC2OfgXqTBjCIcMptpR/GIlGqbe4aFVJcy9NEVAFx7sHiLuAb+VNnec3XHHC+xOk3MLzDA==
+"""""
+        peer = Peer.from_signed_raw(signed_raw)
+        pubkey = "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU"
+        verifying_key = VerifyingKey(pubkey)
+        self.assertTrue(verifying_key.verify_document(peer))
-- 
GitLab