Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ This package allows generating mnemonics, seeds, private/public keys and address
- Mnemonic and seed generation for [Substrate](https://wiki.polkadot.network/docs/learn-accounts#seed-generation) (Polkadot/Kusama ecosystem)
- Keys derivation for [Substrate](https://wiki.polkadot.network/docs/learn-accounts#derivation-paths) (Polkadot/Kusama ecosystem, same as Polkadot-JS)
- Keys and addresses generation for Cardano (Byron-Legacy, Byron-Icarus and Shelley, same as Ledger and AdaLite/Yoroi wallets)
- Mnemonic and seed generation for Monero
- Mnemonic and seed generation for Monero (legacy and Polyseed)
- Keys and addresses/subaddresses generation for Monero (same as the official Monero wallet)
- Mnemonic and seed generation for Algorand (Algorand 25-word mnemonic)
- Mnemonic and seed generation like Electrum wallet (v1 and v2)
Expand Down
19 changes: 18 additions & 1 deletion bip_utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@
from bip_utils.monero.conf import MoneroCoins, MoneroConf

# Monero mnemonic
from bip_utils.monero.mnemonic import (
from bip_utils.monero.mnemonic_legacy import (
MoneroEntropyBitLen,
MoneroEntropyGenerator,
MoneroLanguages,
Expand All @@ -342,6 +342,23 @@
MoneroWordsNum,
)

# Monero Polyseed mnemonic
from bip_utils.monero.mnemonic_polyseed import (
MoneroPolyseedCoins,
MoneroPolyseedDecodedData,
MoneroPolyseedEntropyBitLen,
MoneroPolyseedEntropyGenerator,
MoneroPolyseedLanguages,
MoneroPolyseedMnemonic,
MoneroPolyseedMnemonicDecoder,
MoneroPolyseedMnemonicEncoder,
MoneroPolyseedMnemonicEncrypter,
MoneroPolyseedMnemonicGenerator,
MoneroPolyseedMnemonicValidator,
MoneroPolyseedSeedGenerator,
MoneroPolyseedWordsNum,
)

# SLIP32
from bip_utils.slip.slip32 import (
Slip32DeserializedKey,
Expand Down
11 changes: 0 additions & 11 deletions bip_utils/monero/mnemonic/__init__.py

This file was deleted.

11 changes: 11 additions & 0 deletions bip_utils/monero/mnemonic_legacy/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from bip_utils.monero.mnemonic_legacy.monero_entropy_generator import MoneroEntropyBitLen, MoneroEntropyGenerator
from bip_utils.monero.mnemonic_legacy.monero_mnemonic import MoneroLanguages, MoneroMnemonic, MoneroWordsNum
from bip_utils.monero.mnemonic_legacy.monero_mnemonic_decoder import MoneroMnemonicDecoder
from bip_utils.monero.mnemonic_legacy.monero_mnemonic_encoder import (
MoneroMnemonicEncoder,
MoneroMnemonicNoChecksumEncoder,
MoneroMnemonicWithChecksumEncoder,
)
from bip_utils.monero.mnemonic_legacy.monero_mnemonic_generator import MoneroMnemonicGenerator
from bip_utils.monero.mnemonic_legacy.monero_mnemonic_validator import MoneroMnemonicValidator
from bip_utils.monero.mnemonic_legacy.monero_seed_generator import MoneroSeedGenerator
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@

from typing_extensions import override

from bip_utils.monero.mnemonic.monero_mnemonic import MoneroLanguages, MoneroMnemonic, MoneroMnemonicConst
from bip_utils.monero.mnemonic.monero_mnemonic_utils import (
from bip_utils.monero.mnemonic_legacy.monero_mnemonic import MoneroLanguages, MoneroMnemonic, MoneroMnemonicConst
from bip_utils.monero.mnemonic_legacy.monero_mnemonic_utils import (
MoneroMnemonicUtils,
MoneroWordsListFinder,
MoneroWordsListGetter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@

from typing_extensions import override

from bip_utils.monero.mnemonic.monero_entropy_generator import MoneroEntropyGenerator
from bip_utils.monero.mnemonic.monero_mnemonic import MoneroLanguages, MoneroMnemonic
from bip_utils.monero.mnemonic.monero_mnemonic_utils import MoneroMnemonicUtils, MoneroWordsListGetter
from bip_utils.monero.mnemonic_legacy.monero_entropy_generator import MoneroEntropyGenerator
from bip_utils.monero.mnemonic_legacy.monero_mnemonic import MoneroLanguages, MoneroMnemonic
from bip_utils.monero.mnemonic_legacy.monero_mnemonic_utils import MoneroMnemonicUtils, MoneroWordsListGetter
from bip_utils.utils.mnemonic import Mnemonic, MnemonicEncoderBase, MnemonicUtils


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
# Imports
from typing import Dict, Union

from bip_utils.monero.mnemonic.monero_entropy_generator import MoneroEntropyBitLen, MoneroEntropyGenerator
from bip_utils.monero.mnemonic.monero_mnemonic import MoneroLanguages, MoneroMnemonicConst, MoneroWordsNum
from bip_utils.monero.mnemonic.monero_mnemonic_encoder import MoneroMnemonicEncoder
from bip_utils.monero.mnemonic_legacy.monero_entropy_generator import MoneroEntropyBitLen, MoneroEntropyGenerator
from bip_utils.monero.mnemonic_legacy.monero_mnemonic import MoneroLanguages, MoneroMnemonicConst, MoneroWordsNum
from bip_utils.monero.mnemonic_legacy.monero_mnemonic_encoder import MoneroMnemonicEncoder
from bip_utils.utils.mnemonic import Mnemonic


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

from typing_extensions import override

from bip_utils.monero.mnemonic.monero_mnemonic import MoneroLanguages, MoneroMnemonicConst
from bip_utils.monero.mnemonic_legacy.monero_mnemonic import MoneroLanguages, MoneroMnemonicConst
from bip_utils.utils.crypto import Crc32
from bip_utils.utils.mnemonic import (
Mnemonic,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
# Imports
from typing import Optional

from bip_utils.monero.mnemonic.monero_mnemonic import MoneroLanguages
from bip_utils.monero.mnemonic.monero_mnemonic_decoder import MoneroMnemonicDecoder
from bip_utils.monero.mnemonic_legacy.monero_mnemonic import MoneroLanguages
from bip_utils.monero.mnemonic_legacy.monero_mnemonic_decoder import MoneroMnemonicDecoder
from bip_utils.utils.mnemonic import MnemonicValidator


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
# Imports
from typing import Optional, Union

from bip_utils.monero.mnemonic.monero_mnemonic import MoneroLanguages
from bip_utils.monero.mnemonic.monero_mnemonic_decoder import MoneroMnemonicDecoder
from bip_utils.monero.mnemonic_legacy.monero_mnemonic import MoneroLanguages
from bip_utils.monero.mnemonic_legacy.monero_mnemonic_decoder import MoneroMnemonicDecoder
from bip_utils.utils.mnemonic import Mnemonic


Expand Down
17 changes: 17 additions & 0 deletions bip_utils/monero/mnemonic_polyseed/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from bip_utils.monero.mnemonic_polyseed.monero_polyseed_entropy_generator import (
MoneroPolyseedEntropyBitLen,
MoneroPolyseedEntropyGenerator,
)
from bip_utils.monero.mnemonic_polyseed.monero_polyseed_mnemonic import (
MoneroPolyseedCoins,
MoneroPolyseedLanguages,
MoneroPolyseedMnemonic,
MoneroPolyseedWordsNum,
)
from bip_utils.monero.mnemonic_polyseed.monero_polyseed_mnemonic_decoder import MoneroPolyseedMnemonicDecoder
from bip_utils.monero.mnemonic_polyseed.monero_polyseed_mnemonic_encoder import MoneroPolyseedMnemonicEncoder
from bip_utils.monero.mnemonic_polyseed.monero_polyseed_mnemonic_encrypter import MoneroPolyseedMnemonicEncrypter
from bip_utils.monero.mnemonic_polyseed.monero_polyseed_mnemonic_generator import MoneroPolyseedMnemonicGenerator
from bip_utils.monero.mnemonic_polyseed.monero_polyseed_mnemonic_utils import MoneroPolyseedDecodedData
from bip_utils.monero.mnemonic_polyseed.monero_polyseed_mnemonic_validator import MoneroPolyseedMnemonicValidator
from bip_utils.monero.mnemonic_polyseed.monero_polyseed_seed_generator import MoneroPolyseedSeedGenerator
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Copyright (c) 2026 Emanuele Bellocchia
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

"""Module for Monero Polyseed entropy generation."""

# Imports
import os
from enum import IntEnum, unique
from typing import List, Union

from typing_extensions import override

from bip_utils.monero.mnemonic_polyseed.monero_polyseed_mnemonic import MoneroPolyseedMnemonicConst
from bip_utils.utils.mnemonic import EntropyGenerator


@unique
class MoneroPolyseedEntropyBitLen(IntEnum):
"""Enumerative for Monero Polyseed entropy bit lengths."""

BIT_LEN_150 = 150


class MoneroPolyseedEntropyGeneratorConst:
"""Class container for Monero Polyseed entropy generator constants."""

# Accepted entropy lengths in bit
ENTROPY_BIT_LEN: List[MoneroPolyseedEntropyBitLen] = [
MoneroPolyseedEntropyBitLen.BIT_LEN_150,
]


class MoneroPolyseedEntropyGenerator(EntropyGenerator):
"""
Monero Polyseed entropy generator class.
It generates random entropy bytes (19 bytes, 150 bits) with top 2 bits of the last byte cleared.
"""

def __init__(self,
bit_len: Union[int, MoneroPolyseedEntropyBitLen] = MoneroPolyseedEntropyBitLen.BIT_LEN_150) -> None:
"""
Construct class.

Args:
bit_len (int or MoneroPolyseedEntropyBitLen): Entropy length in bits

Raises:
ValueError: If the bit length is not valid
"""
if not self.IsValidEntropyBitLen(bit_len):
raise ValueError(f"Entropy bit length is not valid ({bit_len})")
super().__init__(bit_len)

@override
def Generate(self) -> bytes:
"""
Generate random entropy bytes (19 bytes with top 2 bits of the last byte cleared).

Returns:
bytes: Generated entropy bytes
"""
entropy = bytearray(os.urandom(MoneroPolyseedMnemonicConst.SECRET_SIZE))
entropy[MoneroPolyseedMnemonicConst.SECRET_SIZE - 1] &= MoneroPolyseedMnemonicConst.CLEAR_MASK
return bytes(entropy)

@staticmethod
def IsValidEntropyBitLen(bit_len: Union[int, MoneroPolyseedEntropyBitLen]) -> bool:
"""
Get if the specified entropy bit length is valid.

Args:
bit_len (int or MoneroPolyseedEntropyBitLen): Entropy length in bits

Returns:
bool: True if valid, false otherwise
"""
return bit_len in MoneroPolyseedEntropyGeneratorConst.ENTROPY_BIT_LEN

@staticmethod
def IsValidEntropyByteLen(byte_len: int) -> bool:
"""
Get if the specified entropy byte length is valid.

Args:
byte_len (int): Entropy length in bytes

Returns:
bool: True if valid, false otherwise
"""
return byte_len == MoneroPolyseedMnemonicConst.SECRET_SIZE
112 changes: 112 additions & 0 deletions bip_utils/monero/mnemonic_polyseed/monero_polyseed_mnemonic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Copyright (c) 2026 Emanuele Bellocchia
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

"""Module for Monero Polyseed mnemonic."""

# Imports
from enum import IntEnum, unique
from typing import List

from bip_utils.bip.bip39 import Bip39Languages
from bip_utils.utils.mnemonic import Mnemonic, MnemonicLanguages


@unique
class MoneroPolyseedWordsNum(IntEnum):
"""Enumerative for Monero Polyseed words number."""

WORDS_NUM_16 = 16


@unique
class MoneroPolyseedLanguages(MnemonicLanguages):
"""Enumerative for Monero Polyseed languages."""

CHINESE_SIMPLIFIED = Bip39Languages.CHINESE_SIMPLIFIED
CHINESE_TRADITIONAL = Bip39Languages.CHINESE_TRADITIONAL
ENGLISH = Bip39Languages.ENGLISH
FRENCH = Bip39Languages.FRENCH
ITALIAN = Bip39Languages.ITALIAN
KOREAN = Bip39Languages.KOREAN
PORTUGUESE = Bip39Languages.PORTUGUESE


@unique
class MoneroPolyseedCoins(IntEnum):
"""Enumerative for Monero Polyseed coins."""

MONERO = 0
AEON = 1
WOWNERO = 2


class MoneroPolyseedMnemonicConst:
"""Class container for Monero Polyseed mnemonic constants."""

# Accepted mnemonic word numbers
MNEMONIC_WORD_NUM: List[MoneroPolyseedWordsNum] = [
MoneroPolyseedWordsNum.WORDS_NUM_16,
]

# GF(2048) parameters
GF_BITS: int = 11
GF_SIZE: int = 2048
GF_MASK: int = 2047
POLY_NUM_CHECK_DIGITS: int = 1
NUM_WORDS: int = 16

# Secret parameters
SECRET_BITS: int = 150
SECRET_SIZE: int = 19
SECRET_BUFFER_SIZE: int = 32
CLEAR_BITS: int = 2
CLEAR_MASK: int = 0x3F

# Date parameters
DATE_BITS: int = 10
DATE_MASK: int = 1023
EPOCH: int = 1635768000
TIME_STEP: int = 2629746

# Feature parameters
FEATURE_BITS: int = 5
FEATURE_MASK: int = 31
USER_FEATURES: int = 3
USER_FEATURES_MASK: int = 7
ENCRYPTED_MASK: int = 16

# Share bits per word (from secret)
SHARE_BITS: int = 10

# Data words (non-check)
DATA_WORDS: int = 15

# KDF parameters
KDF_NUM_ITERATIONS: int = 10000
KDF_KEY_SIZE: int = 32
KDF_KEY_SALT_PREFIX: bytes = b"POLYSEED key"
KDF_MASK_SALT: bytes = b"POLYSEED mask\x00\xff\xff"

# GF(2048) multiplication-by-2 lookup table
MUL2_TABLE: List[int] = [5, 7, 1, 3, 13, 15, 9, 11]


class MoneroPolyseedMnemonic(Mnemonic):
"""Monero Polyseed mnemonic class (alias for Mnemonic)."""
Loading
Loading