Skip to content

Commit

Permalink
16 Nov update. singer.py added. test_stamps.py added. test_signer.py …
Browse files Browse the repository at this point in the history
…added
  • Loading branch information
Aviksaikat committed Nov 17, 2023
1 parent e8d4b76 commit 01c2a75
Show file tree
Hide file tree
Showing 12 changed files with 224 additions and 76 deletions.
52 changes: 24 additions & 28 deletions pdm.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 10 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ version = "0.1.0"
description = "Python client library for connecting to Bee decentralised storage"
authors = [{ name = "SAIKAT KARMAKAR", email = "saikickkarma@protonmail.com" }]
dependencies = [
"eth-ape>=0.6.19",
"eth-ape>=0.6.25",
]
requires-python = ">=3.9"
readme = "README.md"
Expand Down Expand Up @@ -50,7 +50,7 @@ lint = [
"ruff>=0.1.5", # Auto-formatter and linter
"mypy>=1.7.0", # Static type analyzer
"types-PyYAML>=6.0.12.12", # Needed due to mypy typeshed
"types-requests>=2.31.0.10", # Needed due to mypy typeshed
"types-requests", # Needed due to mypy typeshed
"types-setuptools>=68.2.0.1", # Needed due to mypy typeshed
"flake8>=6.1.0", # Style linter
"flake8-breakpoint>=1.1.0", # detect breakpoints left in code
Expand Down Expand Up @@ -156,3 +156,11 @@ tests = ["tests", "*/bee-py/tests"]

[tool.coverage.report]
exclude_lines = ["no cov", "if __name__ == .__main__.:", "if TYPE_CHECKING:"]


[tool.pytest.ini_options]
norecursedirs = "projects"
addopts = "-p no:ape_test" # NOTE: Prevents the ape plugin from activating on our tests
python_files = "test_*.py"
testpaths = "tests"
markers = "fuzzing: Run Hypothesis fuzz test suite"
101 changes: 101 additions & 0 deletions src/bee_py/chunk/signer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
from typing import Optional, Union

from ape.managers.accounts import AccountAPI
from ape.types import AddressType
from ape.types.signatures import MessageSignature, recover_signer
from eth_account.messages import SignableMessage, encode_defunct
from eth_utils import keccak
from hexbytes import HexBytes

from bee_py.utils.hash import keccak256_hash

# Variables
UNCOMPRESSED_RECOVERY_ID = 27


def hash_with_ethereum_prefix(data: Union[bytes, bytearray]) -> bytes:
"""
Calculates the Keccak-256 hash of the provided data, prefixed with the Ethereum signed message prefix.
Args:
data (bytes): The data to be hashed.
Returns:
bytes: The Keccak-256 hash of the prefixed data.
"""

ethereum_signed_message_prefix = f"\x19Ethereum Signed Message:\n{len(data)}"
prefix_bytes = ethereum_signed_message_prefix.encode("utf-8")

return keccak256_hash(prefix_bytes, data)


# TODO: Update the implementation when this PR is merged https://github.com/ApeWorX/ape/pull/1734
def sign(
data: Union[str, bytes, bytearray], account: AccountAPI, auto_sign: Optional[bool] = False # noqa: FBT002
) -> HexBytes:
"""
Calculates the signature of the provided data using the given private key.
Args:
data(str, bytes, bytearray): The data to be signed.
account: ape account
auto_sign(Optional[bool]): Whether to enable auto-signing for the account
Returns:
HexBytes -> The signature of the data as HexBytes
N.B. It is not recoomened to pass private key here & there that's why I
thought to use ape's account container which is much more secure that just
passing the public key while calling this function.
"""

if isinstance(data, str):
data = encode_defunct(text=data)

# you have to set password as env variable
# more info here: https://docs.apeworx.io/ape/stable/userguides/accounts.html#keyfile-passphrase-environment-variable-more-secure
if auto_sign:
account.set_autosign(True)

signature = account.sign_message(data)

# return the signature encoded in vrs format
return HexBytes(signature.encode_vrs())


# for more info ckeckout my gist: https://gist.github.com/Aviksaikat/fd5dfaef4c69e23116148b4b7c0377b6
def public_key_to_address(pub_key: Union[str, bytes, HexBytes]) -> HexBytes[AddressType]:
"""
Converts an elliptic curve public key into its corresponding Ethereum address.
Args:
pub_key (str | bytes | HexBytes): The elliptic curve public key.
Returns:
EthAddress(HexBytes): The Ethereum address derived from the public key.
"""
if isinstance(pub_key, HexBytes):
pub_key = pub_key.hex()
hash_of_public_key = keccak(pub_key)

# Extract the last 20 bytes (40 characters) from the keccak digest as the address
address = hash_of_public_key[24:]
return HexBytes(address)


def recover_addres(message: SignableMessage, signature: MessageSignature) -> AddressType:
"""
Recovers the Ethereum address from a given signature and message digest.
This function can be used to verify the authenticity of a message by comparing
the recovered address with the actual address of the signer.
Args:
message (SignableMessage): The signature generated by the signer.
signature (MessageSignature): The message digest of the data to be verified.
Returns:
AddressType: The recovered Ethereum address.
"""
return recover_signer(message, signature)
3 changes: 3 additions & 0 deletions src/bee_py/types/type.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
REFERENCE_BYTES_LENGTH = 32
ENCRYPTED_REFERENCE_BYTES_LENGTH = 64

SIGNATURE_HEX_LENGTH = 130
SIGNATURE_BYTES_LENGTH = 65

# Minimal depth that can be used for creation of postage batch
STAMPS_DEPTH_MIN = 17

Expand Down
Loading

0 comments on commit 01c2a75

Please sign in to comment.