diff --git a/duniterpy/key/signing_key.py b/duniterpy/key/signing_key.py
index 45696723d0eb68cc88f65e7f97f737abee8e9b83..87da804e7090069419ab9cab27b4214b105d7f53 100644
--- a/duniterpy/key/signing_key.py
+++ b/duniterpy/key/signing_key.py
@@ -17,12 +17,16 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import base64
 import re
+import struct
+from os import PathLike
 from typing import Optional, Union, TypeVar, Type
 
 import libnacl.sign
 import pyaes
 from libnacl.utils import load_key
-from hashlib import scrypt
+from hashlib import scrypt, sha256
+
+from pyaes import AESModeOfOperationECB
 
 from .scrypt_params import ScryptParams
 from .base58 import Base58Encoder
@@ -31,8 +35,25 @@ from ..tools import (
     xor_bytes,
     convert_seedhex_to_seed,
     convert_seed_to_seedhex,
+    dubp_mnemonic_to_seed,
 )
 
+DEWIF_CURRENCY_CODE_NONE = 0x00000000
+DEWIF_CURRENCY_CODE_G1 = 0x00000001
+DEWIF_CURRENCY_CODE_G1_TEST = 0x10000001
+
+
+def chunkstring(data: bytes, length: int):
+    """
+    Return a tuple of chunks sized at length from the data bytes
+
+    :param data: Data to split
+    :param length: Size of  chunks
+    :return:
+    """
+    return (data[0 + i : length + i] for i in range(0, len(data), length))
+
+
 # required to type hint cls in classmethod
 SigningKeyType = TypeVar("SigningKeyType", bound="SigningKey")
 
@@ -509,3 +530,13 @@ Data: {data}""".format(
         seed = bytes(base64.b64decode(secret)[0:32])
 
         return cls(seed)
+
+    @classmethod
+    def from_dubp_mnemonic(cls, mnemonic: str):
+        """
+        Generate key pair instance from a DUBP mnemonic passphrase (128 bits, twelve words)
+
+        :param mnemonic: DUBP mnemonic passphrase
+        :return:
+        """
+        return cls(dubp_mnemonic_to_seed(mnemonic))
diff --git a/duniterpy/tools.py b/duniterpy/tools.py
index a613e642defd524876c65534bfd12529b44e5504..3e594d19ff4e1c5cbd7dfc313e817284c3bfd5e8 100644
--- a/duniterpy/tools.py
+++ b/duniterpy/tools.py
@@ -16,9 +16,12 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 
 import uuid
+from hashlib import sha256, scrypt
 from typing import Union
 from libnacl.encode import hex_decode, hex_encode
 
+from duniterpy.key.scrypt_params import ScryptParams
+
 
 def ensure_bytes(data: Union[str, bytes]) -> bytes:
     """
@@ -87,3 +90,18 @@ def get_ws2p_challenge() -> str:
     :rtype str:
     """
     return str(uuid.uuid4()) + str(uuid.uuid4())
+
+
+def dubp_mnemonic_to_seed(mnemonic: str) -> bytes:
+    """
+    Return a seed from a 128 bits mnemonic (twelve words)
+
+    :param mnemonic: 128 bits mnemonic
+    :return:
+    """
+    password = mnemonic.encode("utf-8")  # type: bytes
+    salt = sha256(b"dubp" + password).digest()  # type: bytes
+    seed = scrypt(
+        password=password, salt=salt, n=4096, r=16, p=1, dklen=32
+    )  # type: bytes
+    return seed
diff --git a/tests/key/test_signing_key.py b/tests/key/test_signing_key.py
index 1bd9a4ae02935d36c14efd464a512cd49c62cee7..3ddf8b2fcd8304f3f3e9cf073c978a4bf7ed9fe2 100644
--- a/tests/key/test_signing_key.py
+++ b/tests/key/test_signing_key.py
@@ -14,7 +14,7 @@ GNU General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
-
+import base64
 import os
 
 from duniterpy.key import VerifyingKey, SigningKey, PublicKey
@@ -144,3 +144,16 @@ class TestSigningKey(unittest.TestCase):
             sign_key_load.vk.hex(),
             "d27f4cb2bfadbaf45b61714b896d4639ab90db035aee746611cdd342bdaa8996",
         )
+
+    def test_dubp_mnemonic(self):
+        mnemonic = (
+            "tongue cute mail fossil great frozen same social weasel impact brush kind"
+        )
+
+        keypair = SigningKey.from_dubp_mnemonic(mnemonic)
+
+        self.assertEqual(
+            base64.b64encode(keypair.seed).decode("utf-8"),
+            "qGdvpbP9lJe7ZG4ZUSyu33KFeAEs/KkshAp9gEI4ReY=",
+        )
+        self.assertEqual(keypair.pubkey, "732SSfuwjB7jkt9th1zerGhphs6nknaCBCTozxUcPWPU")
diff --git a/tests/test_tools.py b/tests/test_tools.py
new file mode 100644
index 0000000000000000000000000000000000000000..0ce1c14a3e2cf1ff2024ff1b697a4b3a353fcbee
--- /dev/null
+++ b/tests/test_tools.py
@@ -0,0 +1,21 @@
+import base64
+import unittest
+
+from duniterpy import tools
+
+
+class TestTools(unittest.TestCase):
+    def test_dubp_mnemonic_to_seed(self):
+        """
+        https://git.duniter.org/documents/rfcs/blob/dubp-mnemonic/rfc/0014_Dubp_Mnemonic.md
+
+        :return:
+        """
+        mnemonic = (
+            "tongue cute mail fossil great frozen same social weasel impact brush kind"
+        )
+        seed = tools.dubp_mnemonic_to_seed(mnemonic)
+        self.assertEqual(
+            "qGdvpbP9lJe7ZG4ZUSyu33KFeAEs/KkshAp9gEI4ReY=",
+            base64.b64encode(seed).decode("utf-8"),
+        )