Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create dtnb.py #38

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
92 changes: 92 additions & 0 deletions python/dtnb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
from typing import Sequence

from dataclasses import dataclass
from nacl.encoding import HexEncoder
from nacl.signing import SigningKey, VerifyKey


@dataclass
class Signature(bytes):
data: Sequence[bytes]

def bytes(self):
""" 64-byte sequence signature """
return self.data

def hex(self):
""" Returns the signature as a hex string """
return HexEncoder.encode(self.bytes())

@classmethod
def new(cls, _bytes):
""" Creates a new signature with the given bytes (length 64) """
if len(_bytes) != 64:
raise Exception(f"Expected length of bytes to be 64 but got {len(_bytes)}")

cls.data = _bytes
return cls()

def verify(self, public_key: Sequence[bytes], message: Sequence[bytes]) -> bool:
vk = VerifyKey(public_key)
return vk.verify(message, self.bytes())


@dataclass
class Wallet:
public_key: Sequence[bytes]
private_key: Sequence[bytes]

@classmethod
def from_bytes(cls, pub: Sequence[bytes], priv: Sequence[bytes]):
if len(pub) != 32:
raise Exception(f"Expected public key to be 32 bytes long not {len(pub)}")
if len(priv) != 32:
raise Exception(f"Expected private key to be 32 bytes long not {len(priv)}")
cls.public_key = pub
cls.private_key = priv
return cls()

@classmethod
def from_hex(cls, pub: str, priv: str):
try:
pub_bytes = HexEncoder.decode(pub)
priv_bytes = HexEncoder.decode(priv)
except:
raise
return cls(pub_bytes, priv_bytes)

@classmethod
def from_private_bytes(cls, priv: Sequence[bytes]):
if len(priv) != 32:
raise Exception(f"Expected private key to be 32 bytes long not {len(priv)}")
key = SigningKey(priv, encoder=HexEncoder)
cls.public_key = key[32:]
cls.private_key = key[:32]
return cls()

@classmethod
def from_private_hex(cls, priv: str):
try:
priv_bytes = HexEncoder.decode(priv)
except:
raise
return cls.from_private_bytes(priv_bytes)

@classmethod
def generate(cls):
priv = SigningKey.generate()
cls.public_key = cls.private_key.verify_key.encode(encoder=HexEncoder)
cls.private_key = priv[:32]
return cls()

@property
def private_key_hex(self):
return HexEncoder.encode(self.private_key)

@property
def public_key_hex(self):
return HexEncoder.encode(self.public_key)

def sign(self, message: Sequence[bytes]) -> Signature:
full_priv = self.private_key.append(self.public_key)
return Signature(SigningKey(full_priv, encoder=HexEncoder), message)
39 changes: 39 additions & 0 deletions python/dtnb_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from typing import Annotated, Sequence
from dtnb import Wallet


class DemoKeys:
private_hex: str
public_hex: str
signature_mocks: Annotated[Sequence[bytes], 2] # list of 2 items containing message and signature

def __init__(self, priv: str, pub: str, signature: Annotated[Sequence[bytes], 2]):
self.private_hex = priv
self.public_hex = pub
self.signature_mocks = signature


def demo_keys():
return (
DemoKeys(
"80811257e5bc79976cba8fd689efe737947caf4e2a741ca11edb601ae3ab654d",
"4c41c0f516401d8ac975eae151bd6fda312cc81e5ce412f041373996a48cf762",
["HELLO, WORLD!", "5e9544bef0046166f15353a0298f41fc7791f1d66203cea659422b6e1a7f12737cffcb5fd71dac1d8f631703a09e9fd03210a6748af5e61cf1c1c3453060760b"]
),
DemoKeys("5a9299a36b91c82918fa5b3d4ea5144cc588c20e66aadb44812d4f2eac953a76", "4299a3508b6207a560143a87dbefc9273e13487f49fc79b31e22a02330947141", ["HELLO, WORLD!",
"307d9fa244cf0a38bba092588a90dcd03cee190214fdc2362c3d0c14b8d768b36fc36716915747642f6144b0171fe95c56034dd203e7191bc4b2012dbbbefe02"]
),
DemoKeys("09645e081d7d9e3bc01ec94081cf4048244ecf4dc8098b4b0a8275cee07003aa", "1c25ff99a7fded3d632146616fd58c3a32b4cc683e04cfc53d8bbc5e59ef38ce",
["HELLO, WORLD!", "b355dd1fd6b1ba6cd529c10a6a6a732ca6eb8417d12fbf29344cdc5425dc4cc1a24efc9db04f9530a18150be0ba9d5844e4da0be87e6e19d224b9670da13d007"]
)
)


def test_creating_wallets_from_keys():
for dk in demo_keys():
wallet = Wallet.from_hex(dk.public_hex, dk.private_hex)


if __name__ == "__main__":

test_creating_wallets_from_keys()