<jupyter_start><jupyter_text>Exercise 1Find out which points are valid on the curve \\( y^2 = x^3 + 7: F_{223} \\)```(192,105), (17,56), (200,119), (1,193), (42,99)```<jupyter_code># Exercise 1

from ecc import FieldElement, Point
prime = 223
a = FieldElement(0, prime)
b = FieldElement(7, prime)
points = ((192,105), (17,56), (200,119), (1,193), (42,99))
# iterate over points

for x_raw, y_raw in points:
    
    # Initialize points this way:
    x = FieldElement(x_raw, prime)
    y = FieldElement(y_raw, prime)


    # try initializing, ValueError means not on curve
    try:
        p = Point(x, y, a, b)
        print(f'Point ({x_raw}, {y_raw}) is on the curve.')
    except ValueError:
        print(f'Point ({x_raw}, {y_raw}) is NOT on the curve.')<jupyter_output>Point (192, 105) is on the curve.
Point (17, 56) is on the curve.
Point (200, 119) is NOT on the curve.
Point (1, 193) is on the curve.
Point (42, 99) is NOT on the curve.<jupyter_text>Exercise 2 Make [this test](/edit/session2/ecc.py) pass: `ecc.py:ECCTest:test_on_curve`<jupyter_code># Exercise 2

reload(ecc)
run(ecc.ECCTest('test_on_curve'))
from ecc import FieldElement, Point
# Example where x1 != x2
prime = 137
a = FieldElement(0, prime)
b = FieldElement(7, prime)
p1 = Point(FieldElement(73, prime), FieldElement(128, prime), a, b)
p2 = Point(FieldElement(46, prime), FieldElement(22, prime), a, b)
print(p1+p2)<jupyter_output>Point(99,49)_137<jupyter_text>Exercise 3Find the following point additions on the curve  \\( y^2 = x^3 + 7: F_{223} \\)```(192,105) + (17,56), (47,71) + (117,141), (143,98) + (76,66)```<jupyter_code># Exercise 3

prime = 223
a = FieldElement(0, prime)
b = FieldElement(7, prime)
additions = ((192, 105, 17, 56), (47, 71, 117, 141), (143, 98, 76, 66))
# iterate over the additions to be done
for x1_raw, y1_raw, x2_raw, y2_raw in additions:
    # Initialize points this way:
    x1 = FieldElement(x1_raw, prime)
    y1 = FieldElement(y1_raw, prime)
    p1 = Point(x1, y1, a, b)
    x2 = FieldElement(x2_raw, prime)
    y2 = FieldElement(y2_raw, prime)
    p2 = Point(x2, y2, a, b)
    print(p1 + p2)<jupyter_output>Point(170,142)_223
Point(60,139)_223
Point(47,71)_223<jupyter_text>Exercise 4 Make [this test](/edit/session2/ecc.py) pass: `ecc.py:ECCTest:test_add`<jupyter_code># Exercise 4

reload(ecc)
run(ecc.ECCTest('test_add'))
from ecc import FieldElement, Point
# Example where x1 != x2
prime = 137
a = FieldElement(0, prime)
b = FieldElement(7, prime)
p = Point(FieldElement(73, prime), FieldElement(128, prime), a, b)
print(p+p)<jupyter_output>Point(103,76)_137<jupyter_text>Exercise 5Find the following scalar multiplications on the curve  \\( y^2 = x^3 + 7: F_{223} \\)* 2*(192,105)* 2*(143,98)* 2*(47,71)* 4*(47,71)* 8*(47,71)* 21*(47,71) Hint: add the point to itself n times<jupyter_code># Exercise 5

prime = 223
a = FieldElement(0, prime)
b = FieldElement(7, prime)
multiplications = ((2, 192, 105), (2, 143, 98), (2, 47, 71), (4, 47, 71), (8, 47, 71), (21, 47, 71))
# iterate over the multiplications
for n, x_raw, y_raw in multiplications:
    # Initialize points this way:
    x = FieldElement(x_raw, prime)
    y = FieldElement(y_raw, prime)
    p = Point(x, y, a, b)

    product = Point(None, None, a, b)
    for _ in range(n):
        product += p

    print(product)
from ecc import FieldElement, Point
# Group Example
prime = 223
a = FieldElement(0, prime)
b = FieldElement(7, prime)
g = Point(FieldElement(47, prime), FieldElement(71, prime), a, b)
inf = Point(None, None, a, b)
total = g
count = 1
while total != inf:
    print(f'{count}:{total}')
    total += g
    count += 1
print(f'{count}:{total}')<jupyter_output><empty_output><jupyter_text>Exercise 6Find out what the order of the group generated by (15, 86) is on  \\( y^2 = x^3 + 7: F_{223} \\) Hint: add the point to itself until you get the point at infinity<jupyter_code># Exercise 6

prime = 223
a = FieldElement(0, prime)
b = FieldElement(7, prime)
x = FieldElement(15, prime)
y = FieldElement(86, prime)
p = Point(x, y, a, b)
inf = Point(None, None, a, b)
# start product at point

# start counter at 1

product = p
counter = 1
while product != inf:
    product += p
    counter += 1

print(counter)<jupyter_output>7<jupyter_text>Exercise 7 Make [this test](/edit/session2/ecc.py) pass: `ecc.py:ECCTest:test_rmul`<jupyter_code># Exercise 7

reload(ecc)
run(ecc.ECCTest('test_rmul'))
# Confirgming G is on the curve
p = 2**256 - 2**32 - 977
x = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
y = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8
print(y**2 % p == (x**3 + 7) % p)
# Confirming order of G is n
from ecc import G
n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
print(n*G)
# Getting the public point from a secret
from ecc import G
secret = 999
point = secret*G
print(point)<jupyter_output><empty_output><jupyter_text>Exercise 8Get the public point where the scalar is the following:* 7* 1485* \\(2^{128}\\)* \\(2^{240}+2^{31}\\)<jupyter_code># Exercise 8

from ecc import G
secrets = (7, 1485, 2**128, 2**240+2**31)
# iterate over secrets
for secret in secrets:
    point = secret * G
    print(point)
    # get the public point<jupyter_output>S256Point(5cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc,6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da)
S256Point(c982196a7466fbbbb0e27a940b6af926c1a74d5ad07128c82824a11b5398afda,7a91f9eae64438afb9ce6448a1c133db2d8fb9254e4546b6f001637d50901f55)
S256Point(8f68b9d2f63b5f339239c1ad981f162ee88c5678723ea3351b7b444c9ec4c0da,662a9f2dba063986de1d90c2b6be215dbbea2cfe95510bfdf23cbf79501fff82)
S256Point(9577ff57c8234558f293df502ca4f09cbc65a6572c842b39b366f21717945116,10b49c67fa9365ad7b90dab070be339a1daf9052373ec30ffae4f72d5e66d053)<jupyter_text>Exercise 9 Make [this test](/edit/session2/ecc.py) pass: `ecc.py:S256Test:test_pubpoint`<jupyter_code># Exercise 9

reload(ecc)
run(ecc.S256Test('test_pubpoint'))
# SEC Example
from ecc import S256Point
point = S256Point(0x5CBDF0646E5DB4EAA398F365F2EA7A0E3D419B7E0330E39CE92BDDEDCAC4F9BC, 0x6AEBCA40BA255960A3178D6D861A54DBA813D0B813FDE7B5A5082628087264DA)
uncompressed = b'\x04' + point.x.num.to_bytes(32, 'big') + point.y.num.to_bytes(32, 'big')
print(uncompressed.hex())
if point.y.num % 2 == 1:
    compressed = b'\x03' + point.x.num.to_bytes(32, 'big')
else:
    compressed = b'\x02' + point.x.num.to_bytes(32, 'big')
print(compressed.hex())<jupyter_output>045cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da
025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc<jupyter_text>Exercise 10Find the compressed and uncompressed SEC format for pub keys where the private keys are:```999**3, 123, 42424242```<jupyter_code># Exercise 10

from ecc import G
secrets = (999**3, 123, 42424242)
# iterate through secrets
for secret in secrets:
    p = secret * G
    x = p.x.num.to_bytes(32, 'big')
    y = p.y.num.to_bytes(32, 'big')
    
    uncompressed = b'\x04' + x + y
    even = point.y.num % 2 == 0
    
    if even:
        compressed = b'\x02' + x
    else:
        compressed = b'\x03' + x
    
    print(uncompressed.hex())
    print('')
    print(compressed.hex())




    # print the .hex() of both<jupyter_output>049d5ca49670cbe4c3bfa84c96a8c87df086c6ea6a24ba6b809c9de234496808d56fa15cc7f3d38cda98dee2419f415b7513dde1301f8643cd9245aea7f3f911f9

029d5ca49670cbe4c3bfa84c96a8c87df086c6ea6a24ba6b809c9de234496808d5
<KEY>

02a598a8030da6d86c6bc7f2f5144ea549d28211ea58faa70ebf4c1e665c1fe9b5
04aee2e7d843f7430097859e2bc603abcc3274ff8169c1a469fee0f20614066f8e21ec53f40efac47ac1c5211b2123527e0e9b57ede790c4da1e72c91fb7da54a3

02aee2e7d843f7430097859e2bc603abcc3274ff8169c1a469fee0f20614066f8e<jupyter_text>Exercise 11 Make [this test](/edit/session2/ecc.py) pass: `ecc.py:S256Test:test_sec`<jupyter_code># Exercise 11

reload(ecc)
run(ecc.S256Test('test_sec'))
# Address Example
from helper import encode_base58, hash160, hash256
sec = bytes.fromhex('025CBDF0646E5DB4EAA398F365F2EA7A0E3D419B7E0330E39CE92BDDEDCAC4F9BC')
h160 = hash160(sec)
raw = b'\x00' + h160
raw = raw + hash256(raw)[:4]
addr = encode_base58(raw)
print(addr)<jupyter_output>19ZewH8Kk1PDbSNdJ97FP4EiCjTRaZMZQA<jupyter_text>Exercise 12Find the mainnet and testnet addresses corresponding to the private keys:* \\(888^3\\), compressed* 321, uncompressed* 4242424242, uncompressed<jupyter_code># Exercise 12

from ecc import G
from helper import encode_base58, hash160, hash256
components = (
    # (secret, compressed)
    (888**3, True),
    (321, False),
    (4242424242, False),
)
# iterate through components
for secret, compressed in components:
    p = secret * G
    sec = p.sec(compressed)
    h160 = hash160(sec)
    
    prefixes = (b'\x00', b'\x6f')
    for prefix in prefixes:
        raw = prefix + h160
        checksum = hash256(raw)[:4]
        addr = encode_base58(raw + checksum)
        print(addr)<jupyter_output>148dY81A9BmdpMhvYEVznrM45kWN32vSCN
mieaqB68xDCtbUBYFoUNcmZNwk74xcBfTP
1S6g2xBJSED7Qr9CYZib5f4PYVhHZiVfj
mfx3y63A7TfTtXKkv7Y6QzsPFY6QCBCXiP
1226JSptcStqn4Yq9aAmNXdwdc2ixuH9nb
mgY3bVusRUL6ZB2Ss999CSrGVbdRwVpM8s<jupyter_text>Exercise 13 Make [this test](/edit/session2/helper.py) pass: `helper.py:HelperTest:test_encode_base58_checksum`<jupyter_code># Exercise 13

reload(helper)
run(helper.HelperTest('test_encode_base58_checksum'))<jupyter_output>.
----------------------------------------------------------------------
Ran 1 test in 0.002s

OK<jupyter_text>Exercise 14 Make [this test](/edit/session2/ecc.py) pass: `ecc.py:S256Test:test_address`<jupyter_code># Exercise 14

reload(ecc)
run(ecc.S256Test('test_address'))<jupyter_output>.
----------------------------------------------------------------------
Ran 1 test in 0.037s

OK<jupyter_text>Exercise 15Create a testnet address using your own secret key (use your name and email as the password if you can't think of anything). Record this secret key for tomorrow!<jupyter_code># Exercise 15

from ecc import G
from helper import little_endian_to_int, hash256
# use a passphrase
passphrase = b'<EMAIL>:<PASSWORD>'
secret = little_endian_to_int(hash256(passphrase))
# get the public point

point = secret * G
print(point.address(testnet=True))<jupyter_output>n2o7SJECe1E56RmLKQ2GuGuZf4YtSZ2KqJ
{'fraction_non_alphanumeric': 0.1313522408285742, 'fraction_numerical': 0.15622882586390474, 'mean_word_length': 5.157330154946365, 'pattern_counts': {'":': 0, '<': 51, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 1, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '15', 'dir': 'jupyter-structured-clean-dedup', 'id': '617396', 'license': 'BSD-2-Clause', 'n_tokens_mistral': 5239, 'n_tokens_neox': 4309, 'n_words': 901, 'path': 'session2/session2.ipynb', 'repo_name': 'sashafklein/programming-blockchain', 'size': '10475'}