ready for takeoff

This commit is contained in:
Jimmy Song 2023-10-17 21:54:43 -05:00
parent 8fb382449c
commit aaf9e7b4db
6 changed files with 134 additions and 77 deletions

92
clear.py Normal file
View File

@ -0,0 +1,92 @@
raw_items = """ecc.S256Point.xonly
ecc.S256Point.verify_schnorr
ecc.PrivateKey.sign_schnorr
ecc.S256Point.tweak
ecc.S256Point.tweaked_key
ecc.S256Point.p2tr_script
ecc.PrivateKey.tweaked_key
taproot.TapLeaf.hash
taproot.TapBranch.hash
taproot.ControlBlock.merkle_root
taproot.ControlBlock.external_pubkey
"""
def chop_word(s):
for i, _ in enumerate(s):
letter = s[i:i+1]
if letter not in "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_":
return s[:i]
raw_items_2 = """hash.tagged_hash
op.op_checksigadd_schnorr
"""
to_clear = {}
files = {}
for item in raw_items_2.split():
components = item.split('.')
files[components[0]] = 1
to_clear[item] = 1
for filename in files.keys():
modified_file = ""
with open(f"session/{filename}.py", "r") as file:
current_func = None
active = False
for line in file:
if line == "\n":
if active:
modified_file += " raise NotImplementedError\n"
active = False
if current_func:
current_func = None
if active:
if line.lstrip().startswith("#") or line.lstrip().startswith("\"\"\""):
modified_file += line
else:
modified_file += line
if line.startswith("def "):
current_func = chop_word(line.lstrip()[4:])
key = f"{filename}.{current_func}"
if to_clear.get(key):
active = True
with open(f"session/{filename}.py", "w") as file:
file.write(modified_file)
to_clear = {}
files = {}
for item in raw_items.split():
components = item.split('.')
files[components[0]] = 1
to_clear[item] = 1
for filename in files.keys():
modified_file = ""
with open(f"session/{filename}.py", "r") as file:
current_class = None
current_func = None
active = False
for line in file:
if line == "\n":
if active:
modified_file += " raise NotImplementedError\n"
active = False
if current_func:
current_func = None
elif current_class:
current_class = None
if active:
if line.lstrip().startswith("#") or line.lstrip().startswith("\"\"\""):
modified_file += line
else:
modified_file += line
if line.startswith("class "):
current_class = chop_word(line[6:])
if line.startswith(" def "):
current_func = chop_word(line.lstrip()[4:])
key = f"{filename}.{current_class}.{current_func}"
if to_clear.get(key):
active = True
with open(f"session/{filename}.py", "w") as file:
file.write(modified_file)

31
restore.py Normal file
View File

@ -0,0 +1,31 @@
from shutil import copy
raw_items = """ecc.S256Point.xonly
ecc.S256Point.verify_schnorr
ecc.PrivateKey.sign_schnorr
ecc.S256Point.tweak
ecc.S256Point.tweaked_key
ecc.S256Point.p2tr_script
ecc.PrivateKey.tweaked_key
taproot.TapLeaf.hash
taproot.TapBranch.hash
taproot.ControlBlock.merkle_root
taproot.ControlBlock.external_pubkey
"""
raw_items_2 = """hash.tagged_hash
op.op_checksigadd_schnorr
"""
files = {}
for item in raw_items.split():
components = item.split('.')
files[components[0]] = 1
for item in raw_items_2.split():
components = item.split('.')
files[components[0]] = 1
for filename in files.keys():
copy(f"session/complete/{filename}.py", f"session/{filename}.py")

View File

@ -271,27 +271,21 @@ class S256Point(Point):
def xonly(self):
"""returns the binary version of X-only pubkey"""
# if x is None, return 32 0 bytes
if self.x is None:
return b"\x00" * 32
# otherwise, convert the x coordinate to Big Endian 32 bytes
return int_to_big_endian(self.x.num, 32)
raise NotImplementedError
def tweak(self, merkle_root=b""):
"""returns the tweak for use in p2tr if there's no script path"""
# take the hash_taptweak of the xonly and the merkle root
tweak = hash_taptweak(self.xonly() + merkle_root)
return tweak
raise NotImplementedError
def tweaked_key(self, merkle_root=b""):
"""Creates the tweaked external key for a particular tweak."""
# Get the tweak from the merkle root
tweak = self.tweak(merkle_root)
# t is the tweak interpreted as big endian
t = big_endian_to_int(tweak)
# Q = P + tG
external_key = self + t * G
# return the external key
return external_key
raise NotImplementedError
def hash160(self, compressed=True):
# get the sec
@ -634,42 +628,20 @@ class PrivateKey:
# to a known value to make k deterministic
# the idea of k generation here is to mix in the private key
# and the msg to ensure it's unique and not reused
if aux is None:
aux = b"\x00" * 32
if self.point.parity:
d = N - self.secret
else:
d = self.secret
if len(msg) != 32:
raise ValueError("msg needs to be 32 bytes")
if len(aux) != 32:
raise ValueError("aux needs to be 32 bytes")
# t contains the secret, msg is added so it's unique to the
# message and private key
t = xor_bytes(int_to_big_endian(d, 32), hash_aux(aux))
k = big_endian_to_int(hash_nonce(t + self.point.xonly() + msg)) % N
# get the resulting R=kG point
r = k * G
# if R's y coordinate is odd, flip the k
if r.parity:
# set k to N - k
k = N - k
# recalculate R
r = k * G
# calculate the commitment which is: R || P || msg
commitment = r.xonly() + self.point.xonly() + msg
# hash_challenge the result and interpret as a big endian integer
# mod the result by N and this is your e
e = big_endian_to_int(hash_challenge(commitment)) % N
# calculate s which is (k+ed) mod N
s = (k + e * d) % N
# create a SchnorrSignature object using the R and s
sig = SchnorrSignature(r, s)
# check that this schnorr signature verifies
if not self.point.verify_schnorr(msg, sig):
raise RuntimeError("Bad Signature")
# return the signature
return sig
raise NotImplementedError
def deterministic_k(self, z):
k = b"\x00" * 32
@ -720,13 +692,10 @@ class PrivateKey:
def tweaked_key(self, merkle_root=b""):
# get the tweak from the point's tweak method
tweak = self.point.tweak(merkle_root)
# t is the tweak interpreted as big endian
t = big_endian_to_int(tweak)
# new secret is the secret plus t (make sure to mod by N)
new_secret = (self.secret + t) % N
# create a new instance of this class using self.__class__
return self.__class__(new_secret)
raise NotImplementedError
@classmethod
def parse(cls, wif):

View File

@ -9,9 +9,8 @@ def sha256(x):
def tagged_hash(tag, msg):
# compute the sha256 of the tag using hashlib.sha256
tag_hash = sha256(tag)
# compute the tagged hash by getting the sha256 of the tag hash + tag hash + message
return sha256(tag_hash + tag_hash + msg)
raise NotImplementedError
def hash_aux(msg):

View File

@ -775,38 +775,18 @@ def op_checksigverify_schnorr(stack, tx_obj, input_index):
def op_checksigadd_schnorr(stack, tx_obj, input_index):
# check to see if there's at least 3 elements
if len(stack) < 3:
return False
# pop off the pubkey
pubkey = stack.pop()
# pop off the n
n = decode_num(stack.pop())
# pop off the signature
signature = stack.pop()
# parse the pubkey
point = S256Point.parse_xonly(pubkey)
# if the signature has 0 length, it's not valid
if len(signature) == 0:
stack.append(encode_num(n))
return True
# we handle the hash type here
if len(signature) == 65:
hash_type = signature[-1]
signature = signature[:-1]
else:
hash_type = None
# parse the Schnorr signature
sig = SchnorrSignature.parse(signature)
# get the message from the tx_obj.sig_hash
msg = tx_obj.sig_hash(input_index, hash_type)
# verify the Schnorr signature
if point.verify_schnorr(msg, sig):
# if valid, increment the n and push back on stack
stack.append(encode_num(n + 1))
else:
# if invalid, push back n on stack
stack.append(encode_num(n))
return True
raise NotImplementedError
def op_checkmultisig(stack, tx_obj, input_index):

View File

@ -41,9 +41,8 @@ class TapLeaf:
def hash(self):
# calculate what's getting hashed
content = int_to_byte(self.tapleaf_version) + self.tap_script.serialize()
# return the hash_tapleaf of the content
return hash_tapleaf(content)
raise NotImplementedError
def leaves(self):
return [self]
@ -79,13 +78,8 @@ class TapBranch:
def hash(self):
# get the left and right hashes
left_hash = self.left.hash()
right_hash = self.right.hash()
# use hash_tapbranch on them in alphabetical order
if left_hash < right_hash:
return hash_tapbranch(left_hash + right_hash)
else:
return hash_tapbranch(right_hash + left_hash)
raise NotImplementedError
def leaves(self):
if self._leaves is None:
@ -143,24 +137,16 @@ class ControlBlock:
def merkle_root(self, tap_script):
# create a TapLeaf from the tap_script and the tapleaf version in the control block
leaf = TapLeaf(tap_script, self.tapleaf_version)
# initialize the hash with the leaf's hash
current = leaf.hash()
# go through the hashes in self.hashes
for h in self.hashes:
# set the current hash as the hash_tapbranch of the sorted hashes
if current < h:
current = hash_tapbranch(current + h)
else:
current = hash_tapbranch(h + current)
# return the current hash
return current
raise NotImplementedError
def external_pubkey(self, tap_script):
# get the Merkle Root using self.merkle_root
merkle_root = self.merkle_root(tap_script)
# return the external pubkey using the tweaked_key method of internal pubkey
return self.internal_pubkey.tweaked_key(merkle_root)
raise NotImplementedError
def serialize(self):
s = int_to_byte(self.tapleaf_version + self.parity)