ecc
py
keyboard_arrow_up
School
University of Toronto, Scarborough *
*We aren’t endorsed by this school
Course
UCLCOMP163
Subject
Computer Science
Date
Nov 24, 2024
Type
py
Pages
13
Uploaded by BarristerLarkPerson679
from io import BytesIO
from random import randint
from unittest import TestCase
import hashlib
import hmac
from helper import encode_base58_checksum, hash160
class FieldElement:
def __init__(self, num, prime):
if num >= prime or num < 0:
error = 'Num {} not in field range 0 to {}'.format(
num, prime - 1)
raise ValueError(error)
self.num = num
self.prime = prime
def __repr__(self):
return 'FieldElement_{}({})'.format(self.prime, self.num)
def __eq__(self, other):
if other is None:
return False
return self.num == other.num and self.prime == other.prime
def __ne__(self, other):
# this should be the inverse of the == operator
return not (self == other)
def __add__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot add two numbers in different Fields')
# self.num and other.num are the actual values
# self.prime is what we need to mod against
num = (self.num + other.num) % self.prime
# We return an element of the same class
return self.__class__(num, self.prime)
def __sub__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot subtract two numbers in different Fields')
# self.num and other.num are the actual values
# self.prime is what we need to mod against
num = (self.num - other.num) % self.prime
# We return an element of the same class
return self.__class__(num, self.prime)
def __mul__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot multiply two numbers in different Fields')
# self.num and other.num are the actual values
# self.prime is what we need to mod against
num = (self.num * other.num) % self.prime
# We return an element of the same class
return self.__class__(num, self.prime)
def __pow__(self, exponent):
n = exponent % (self.prime - 1)
num = pow(self.num, n, self.prime)
return self.__class__(num, self.prime)
def __truediv__(self, other):
if self.prime != other.prime:
raise TypeError('Cannot divide two numbers in different Fields')
# self.num and other.num are the actual values
# self.prime is what we need to mod against
# use fermat's little theorem:
# self.num**(p-1) % p == 1
# this means:
# 1/n == pow(n, p-2, p)
num = (self.num * pow(other.num, self.prime - 2, self.prime)) % self.prime
# We return an element of the same class
return self.__class__(num, self.prime)
def __rmul__(self, coefficient):
num = (self.num * coefficient) % self.prime
return self.__class__(num=num, prime=self.prime)
class FieldElementTest(TestCase):
def test_ne(self):
a = FieldElement(2, 31)
b = FieldElement(2, 31)
c = FieldElement(15, 31)
self.assertEqual(a, b)
self.assertTrue(a != c)
self.assertFalse(a != b)
def test_add(self):
a = FieldElement(2, 31)
b = FieldElement(15, 31)
self.assertEqual(a + b, FieldElement(17, 31))
a = FieldElement(17, 31)
b = FieldElement(21, 31)
self.assertEqual(a + b, FieldElement(7, 31))
def test_sub(self):
a = FieldElement(29, 31)
b = FieldElement(4, 31)
self.assertEqual(a - b, FieldElement(25, 31))
a = FieldElement(15, 31)
b = FieldElement(30, 31)
self.assertEqual(a - b, FieldElement(16, 31))
def test_mul(self):
a = FieldElement(24, 31)
b = FieldElement(19, 31)
self.assertEqual(a * b, FieldElement(22, 31))
def test_rmul(self):
a = FieldElement(24, 31)
b = 2
self.assertEqual(b * a, a + a)
def test_pow(self):
a = FieldElement(17, 31)
self.assertEqual(a**3, FieldElement(15, 31))
a = FieldElement(5, 31)
b = FieldElement(18, 31)
self.assertEqual(a**5 * b, FieldElement(16, 31))
def test_div(self):
a = FieldElement(3, 31)
b = FieldElement(24, 31)
self.assertEqual(a / b, FieldElement(4, 31))
a = FieldElement(17, 31)
self.assertEqual(a**-3, FieldElement(29, 31))
a = FieldElement(4, 31)
b = FieldElement(11, 31)
self.assertEqual(a**-4 * b, FieldElement(13, 31))
class Point:
def __init__(self, x, y, a, b):
self.a = a
self.b = b
self.x = x
self.y = y
# x being None and y being None represents the point at infinity
# Check for that here since the equation below won't make sense
# with None values for both.
if self.x is None and self.y is None:
return
# make sure that the elliptic curve equation is satisfied
# y**2 == x**3 + a*x + b
if self.y**2 != self.x**3 + a * x + b:
# if not, throw a ValueError
raise ValueError('({}, {}) is not on the curve'.format(x, y))
def __eq__(self, other):
return self.x == other.x and self.y == other.y \
and self.a == other.a and self.b == other.b
def __ne__(self, other):
# this should be the inverse of the == operator
return not (self == other)
def __repr__(self):
if self.x is None:
return 'Point(infinity)'
elif isinstance(self.x, FieldElement):
return 'Point({},{})_{}_{} FieldElement({})'.format(
self.x.num, self.y.num, self.a.num, self.b.num, self.x.prime)
else:
return 'Point({},{})_{}_{}'.format(self.x, self.y, self.a, self.b)
def __add__(self, other):
if self.a != other.a or self.b != other.b:
raise TypeError('Points {}, {} are not on the same curve'.format(self, other))
# Case 0.0: self is the point at infinity, return other
if self.x is None:
Your preview ends here
Eager to read complete document? Join bartleby learn and gain access to the full version
- Access to all documents
- Unlimited textbook solutions
- 24/7 expert homework help
return other
# Case 0.1: other is the point at infinity, return self
if other.x is None:
return self
# Case 1: self.x == other.x, self.y != other.y
# Result is point at infinity
if self.x == other.x and self.y != other.y:
return self.__class__(None, None, self.a, self.b)
# Case 2: self.x ≠ other.x
# Formula (x3,y3)==(x1,y1)+(x2,y2)
# s=(y2-y1)/(x2-x1)
# x3=s**2-x1-x2
# y3=s*(x1-x3)-y1
if self.x != other.x:
s = (other.y - self.y) / (other.x - self.x)
x = s**2 - self.x - other.x
y = s * (self.x - x) - self.y
return self.__class__(x, y, self.a, self.b)
# Case 4: if we are tangent to the vertical line,
# we return the point at infinity
# note instead of figuring out what 0 is for each type
# we just use 0 * self.x
if self == other and self.y == 0 * self.x:
return self.__class__(None, None, self.a, self.b)
# Case 3: self == other
# Formula (x3,y3)=(x1,y1)+(x1,y1)
# s=(3*x1**2+a)/(2*y1)
# x3=s**2-2*x1
# y3=s*(x1-x3)-y1
if self == other:
s = (3 * self.x**2 + self.a) / (2 * self.y)
x = s**2 - 2 * self.x
y = s * (self.x - x) - self.y
return self.__class__(x, y, self.a, self.b)
def __rmul__(self, coefficient):
coef = coefficient
current = self
result = self.__class__(None, None, self.a, self.b)
while coef:
if coef & 1:
result += current
current += current
coef >>= 1
return result
class PointTest(TestCase):
def test_ne(self):
a = Point(x=3, y=-7, a=5, b=7)
b = Point(x=18, y=77, a=5, b=7)
self.assertTrue(a != b)
self.assertFalse(a != a)
def test_on_curve(self):
with self.assertRaises(ValueError):
Point(x=-2, y=4, a=5, b=7)
# these should not raise an error
Point(x=3, y=-7, a=5, b=7)
Point(x=18, y=77, a=5, b=7)
def test_add0(self):
a = Point(x=None, y=None, a=5, b=7)
b = Point(x=2, y=5, a=5, b=7)
c = Point(x=2, y=-5, a=5, b=7)
self.assertEqual(a + b, b)
self.assertEqual(b + a, b)
self.assertEqual(b + c, a)
def test_add1(self):
a = Point(x=3, y=7, a=5, b=7)
b = Point(x=-1, y=-1, a=5, b=7)
self.assertEqual(a + b, Point(x=2, y=-5, a=5, b=7))
def test_add2(self):
a = Point(x=-1, y=1, a=5, b=7)
self.assertEqual(a + a, Point(x=18, y=-77, a=5, b=7))
class ECCTest(TestCase):
def test_on_curve(self):
# tests the following points whether they are on the curve or not
# on curve y^2=x^3-7 over F_223:
# (192,105) (17,56) (200,119) (1,193) (42,99)
# the ones that aren't should raise a ValueError
prime = 223
a = FieldElement(0, prime)
b = FieldElement(7, prime)
valid_points = ((192, 105), (17, 56), (1, 193))
invalid_points = ((200, 119), (42, 99))
# iterate over valid points
for x_raw, y_raw in valid_points:
x = FieldElement(x_raw, prime)
y = FieldElement(y_raw, prime)
# Creating the point should not result in an error
Point(x, y, a, b)
# iterate over invalid points
for x_raw, y_raw in invalid_points:
x = FieldElement(x_raw, prime)
y = FieldElement(y_raw, prime)
with self.assertRaises(ValueError):
Point(x, y, a, b)
def test_add(self):
# tests the following additions on curve y^2=x^3-7 over F_223:
# (192,105) + (17,56)
# (47,71) + (117,141)
# (143,98) + (76,66)
prime = 223
a = FieldElement(0, prime)
b = FieldElement(7, prime)
additions = (
# (x1, y1, x2, y2, x3, y3)
(192, 105, 17, 56, 170, 142),
(47, 71, 117, 141, 60, 139),
(143, 98, 76, 66, 47, 71),
)
# iterate over the additions
for x1_raw, y1_raw, x2_raw, y2_raw, x3_raw, y3_raw in additions:
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)
x3 = FieldElement(x3_raw, prime)
y3 = FieldElement(y3_raw, prime)
p3 = Point(x3, y3, a, b)
# check that p1 + p2 == p3
self.assertEqual(p1 + p2, p3)
def test_rmul(self):
# tests the following scalar multiplications
# 2*(192,105)
# 2*(143,98)
# 2*(47,71)
# 4*(47,71)
# 8*(47,71)
# 21*(47,71)
prime = 223
a = FieldElement(0, prime)
b = FieldElement(7, prime)
multiplications = (
# (coefficient, x1, y1, x2, y2)
(2, 192, 105, 49, 71),
(2, 143, 98, 64, 168),
(2, 47, 71, 36, 111),
(4, 47, 71, 194, 51),
(8, 47, 71, 116, 55),
(21, 47, 71, None, None),
)
# iterate over the multiplications
for s, x1_raw, y1_raw, x2_raw, y2_raw in multiplications:
x1 = FieldElement(x1_raw, prime)
y1 = FieldElement(y1_raw, prime)
p1 = Point(x1, y1, a, b)
# initialize the second point based on whether it's the point at infinity
if x2_raw is None:
p2 = Point(None, None, a, b)
else:
x2 = FieldElement(x2_raw, prime)
y2 = FieldElement(y2_raw, prime)
p2 = Point(x2, y2, a, b)
Your preview ends here
Eager to read complete document? Join bartleby learn and gain access to the full version
- Access to all documents
- Unlimited textbook solutions
- 24/7 expert homework help
# check that the product is equal to the expected point
self.assertEqual(s * p1, p2)
A = 0
B = 7
P = 2**256 - 2**32 - 977
N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
class S256Field(FieldElement):
def __init__(self, num, prime=None):
super().__init__(num=num, prime=P)
def __repr__(self):
return '{:x}'.format(self.num).zfill(64)
def sqrt(self):
return self**((P + 1) // 4)
class S256Point(Point):
def __init__(self, x, y, a=None, b=None):
a, b = S256Field(A), S256Field(B)
if type(x) == int:
super().__init__(x=S256Field(x), y=S256Field(y), a=a, b=b)
else:
super().__init__(x=x, y=y, a=a, b=b)
def __repr__(self):
if self.x is None:
return 'S256Point(infinity)'
else:
return 'S256Point({}, {})'.format(self.x, self.y)
def __rmul__(self, coefficient):
coef = coefficient % N
return super().__rmul__(coef)
def verify(self, z, sig):
# By Fermat's Little Theorem, 1/s = pow(s, N-2, N)
s_inv = pow(sig.s, N - 2, N)
# u = z / s
u = z * s_inv % N
# v = r / s
v = sig.r * s_inv % N
# u*G + v*P should have as the x coordinate, r
total = u * G + v * self
return total.x.num == sig.r
def sec(self, compressed=True):
'''returns the binary version of the SEC format'''
# if compressed, starts with b'\x02' if self.y.num is even, b'\x03' if self.y is odd
# then self.x.num
# remember, you have to convert self.x.num/self.y.num to binary (some_integer.to_bytes(32, 'big'))
if compressed:
if self.y.num % 2 == 0:
return b'\x02' + self.x.num.to_bytes(32, 'big')
else:
return b'\x03' + self.x.num.to_bytes(32, 'big')
else:
# if non-compressed, starts with b'\x04' followod by self.x and then self.y
return b'\x04' + self.x.num.to_bytes(32, 'big') + \
self.y.num.to_bytes(32, 'big')
def hash160(self, compressed=True):
return hash160(self.sec(compressed))
def address(self, compressed=True, testnet=False):
'''Returns the address string'''
h160 = self.hash160(compressed)
if testnet:
prefix = b'\x6f'
else:
prefix = b'\x00'
return encode_base58_checksum(prefix + h160)
@classmethod
def parse(self, sec_bin):
'''returns a Point object from a SEC binary (not hex)'''
if sec_bin[0] == 4:
x = int.from_bytes(sec_bin[1:33], 'big')
y = int.from_bytes(sec_bin[33:65], 'big')
return S256Point(x=x, y=y)
is_even = sec_bin[0] == 2
x = S256Field(int.from_bytes(sec_bin[1:], 'big'))
# right side of the equation y^2 = x^3 + 7
alpha = x**3 + S256Field(B)
# solve for left side
beta = alpha.sqrt()
if beta.num % 2 == 0:
even_beta = beta
odd_beta = S256Field(P - beta.num)
else:
even_beta = S256Field(P - beta.num)
odd_beta = beta
if is_even:
return S256Point(x, even_beta)
else:
return S256Point(x, odd_beta)
G = S256Point(
0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8)
class S256Test(TestCase):
def test_order(self):
point = N * G
self.assertIsNone(point.x)
def test_pubpoint(self):
# write a test that tests the public point for the following
points = (
# secret, x, y
(7, 0x5cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc,
0x6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da),
(1485, 0xc982196a7466fbbbb0e27a940b6af926c1a74d5ad07128c82824a11b5398afda, 0x7a91f9eae64438afb9ce6448a1c133db2d8fb9254e4546b6f001637d50901f55),
(2**128, 0x8f68b9d2f63b5f339239c1ad981f162ee88c5678723ea3351b7b444c9ec4c0da, 0x662a9f2dba063986de1d90c2b6be215dbbea2cfe95510bfdf23cbf79501fff82),
(2**240 + 2**31, 0x9577ff57c8234558f293df502ca4f09cbc65a6572c842b39b366f21717945116, 0x10b49c67fa9365ad7b90dab070be339a1daf9052373ec30ffae4f72d5e66d053),
)
# iterate over points
for secret, x, y in points:
# initialize the secp256k1 point (S256Point)
point = S256Point(x, y)
# check that the secret*G is the same as the point
self.assertEqual(secret * G, point)
def test_verify(self):
point = S256Point(
0x887387e452b8eacc4acfde10d9aaf7f6d9a0f975aabb10d006e4da568744d06c,
0x61de6d95231cd89026e286df3b6ae4a894a3378e393e93a0f45b666329a0ae34)
z = 0xec208baa0fc1c19f708a9ca96fdeff3ac3f230bb4a7ba4aede4942ad003c0f60
r = 0xac8d1c87e51d0d441be8b3dd5b05c8795b48875dffe00b7ffcfac23010d3a395
s = 0x68342ceff8935ededd102dd876ffd6ba72d6a427a3edb13d26eb0781cb423c4
self.assertTrue(point.verify(z, Signature(r, s)))
z = 0x7c076ff316692a3d7eb3c3bb0f8b1488cf72e1afcd929e29307032997a838a3d
r = 0xeff69ef2b1bd93a66ed5219add4fb51e11a840f404876325a1e8ffe0529a2c
s = 0xc7207fee197d27c618aea621406f6bf5ef6fca38681d82b2f06fddbdce6feab6
self.assertTrue(point.verify(z, Signature(r, s)))
def test_sec(self):
coefficient = 999**3
uncompressed = '049d5ca49670cbe4c3bfa84c96a8c87df086c6ea6a24ba6b809c9de234496808d56fa15cc7f3d38cda
98dee2419f415b7513dde1301f8643cd9245aea7f3f911f9'
compressed = '039d5ca49670cbe4c3bfa84c96a8c87df086c6ea6a24ba6b809c9de234496808d5'
point = coefficient * G
self.assertEqual(point.sec(compressed=False), bytes.fromhex(uncompressed))
self.assertEqual(point.sec(compressed=True), bytes.fromhex(compressed))
coefficient = 123
uncompressed = '04a598a8030da6d86c6bc7f2f5144ea549d28211ea58faa70ebf4c1e665c1fe9b5204b5d6f84822c30
7e4b4a7140737aec23fc63b65b35f86a10026dbd2d864e6b'
compressed = '03a598a8030da6d86c6bc7f2f5144ea549d28211ea58faa70ebf4c1e665c1fe9b5'
point = coefficient * G
self.assertEqual(point.sec(compressed=False), bytes.fromhex(uncompressed))
self.assertEqual(point.sec(compressed=True), bytes.fromhex(compressed))
coefficient = 42424242
uncompressed = '04aee2e7d843f7430097859e2bc603abcc3274ff8169c1a469fee0f20614066f8e21ec53f40efac47a
Your preview ends here
Eager to read complete document? Join bartleby learn and gain access to the full version
- Access to all documents
- Unlimited textbook solutions
- 24/7 expert homework help
c1c5211b2123527e0e9b57ede790c4da1e72c91fb7da54a3'
compressed = '03aee2e7d843f7430097859e2bc603abcc3274ff8169c1a469fee0f20614066f8e'
point = coefficient * G
self.assertEqual(point.sec(compressed=False), bytes.fromhex(uncompressed))
self.assertEqual(point.sec(compressed=True), bytes.fromhex(compressed))
def test_address(self):
secret = 888**3
mainnet_address = '148dY81A9BmdpMhvYEVznrM45kWN32vSCN'
testnet_address = 'mieaqB68xDCtbUBYFoUNcmZNwk74xcBfTP'
point = secret * G
self.assertEqual(
point.address(compressed=True, testnet=False), mainnet_address)
self.assertEqual(
point.address(compressed=True, testnet=True), testnet_address)
secret = 321
mainnet_address = '1S6g2xBJSED7Qr9CYZib5f4PYVhHZiVfj'
testnet_address = 'mfx3y63A7TfTtXKkv7Y6QzsPFY6QCBCXiP'
point = secret * G
self.assertEqual(
point.address(compressed=False, testnet=False), mainnet_address)
self.assertEqual(
point.address(compressed=False, testnet=True), testnet_address)
secret = 4242424242
mainnet_address = '1226JSptcStqn4Yq9aAmNXdwdc2ixuH9nb'
testnet_address = 'mgY3bVusRUL6ZB2Ss999CSrGVbdRwVpM8s'
point = secret * G
self.assertEqual(
point.address(compressed=False, testnet=False), mainnet_address)
self.assertEqual(
point.address(compressed=False, testnet=True), testnet_address)
class Signature:
def __init__(self, r, s):
self.r = r
self.s = s
def __repr__(self):
return 'Signature({:x},{:x})'.format(self.r, self.s)
def der(self):
rbin = self.r.to_bytes(32, byteorder='big')
# remove all null bytes at the beginning
rbin = rbin.lstrip(b'\x00')
# if rbin has a high bit, add a \x00
if rbin[0] & 0x80:
rbin = b'\x00' + rbin
result = bytes([2, len(rbin)]) + rbin # <1>
sbin = self.s.to_bytes(32, byteorder='big')
# remove all null bytes at the beginning
sbin = sbin.lstrip(b'\x00')
# if sbin has a high bit, add a \x00
if sbin[0] & 0x80:
sbin = b'\x00' + sbin
result += bytes([2, len(sbin)]) + sbin
return bytes([0x30, len(result)]) + result
@classmethod
def parse(cls, signature_bin):
s = BytesIO(signature_bin)
compound = s.read(1)[0]
if compound != 0x30:
raise SyntaxError("Bad Signature")
length = s.read(1)[0]
if length + 2 != len(signature_bin):
raise SyntaxError("Bad Signature Length")
marker = s.read(1)[0]
if marker != 0x02:
raise SyntaxError("Bad Signature")
rlength = s.read(1)[0]
r = int.from_bytes(s.read(rlength), 'big')
marker = s.read(1)[0]
if marker != 0x02:
raise SyntaxError("Bad Signature")
slength = s.read(1)[0]
s = int.from_bytes(s.read(slength), 'big')
if len(signature_bin) != 6 + rlength + slength:
raise SyntaxError("Signature too long")
return cls(r, s)
class SignatureTest(TestCase):
def test_der(self):
testcases = (
(1, 2),
(randint(0, 2**256), randint(0, 2**255)),
(randint(0, 2**256), randint(0, 2**255)),
)
for r, s in testcases:
sig = Signature(r, s)
der = sig.der()
sig2 = Signature.parse(der)
self.assertEqual(sig2.r, r)
self.assertEqual(sig2.s, s)
class PrivateKey:
def __init__(self, secret):
self.secret = secret
self.point = secret * G
def hex(self):
return '{:x}'.format(self.secret).zfill(64)
def sign(self, z):
k = self.deterministic_k(z)
# r is the x coordinate of the resulting point k*G
r = (k * G).x.num
# remember 1/k = pow(k, N-2, N)
k_inv = pow(k, N - 2, N)
# s = (z+r*secret) / k
s = (z + r * self.secret) * k_inv % N
if s > N / 2:
s = N - s
# return an instance of Signature:
# Signature(r, s)
return Signature(r, s)
def deterministic_k(self, z):
k = b'\x00' * 32
v = b'\x01' * 32
if z > N:
z -= N
z_bytes = z.to_bytes(32, 'big')
secret_bytes = self.secret.to_bytes(32, 'big')
s256 = hashlib.sha256
k = hmac.new(k, v + b'\x00' + secret_bytes + z_bytes, s256).digest()
v = hmac.new(k, v, s256).digest()
k = hmac.new(k, v + b'\x01' + secret_bytes + z_bytes, s256).digest()
v = hmac.new(k, v, s256).digest()
while True:
v = hmac.new(k, v, s256).digest()
candidate = int.from_bytes(v, 'big')
if candidate >= 1 and candidate < N:
return candidate
k = hmac.new(k, v + b'\x00', s256).digest()
v = hmac.new(k, v, s256).digest()
def wif(self, compressed=True, testnet=False):
# convert the secret from integer to a 32-bytes in big endian using num.to_bytes(32, 'big')
secret_bytes = self.secret.to_bytes(32, 'big')
# prepend b'\xef' on testnet, b'\x80' on mainnet
if testnet:
prefix = b'\xef'
else:
prefix = b'\x80'
# append b'\x01' if compressed
if compressed:
suffix = b'\x01'
else:
suffix = b''
# encode_base58_checksum the whole thing
return encode_base58_checksum(prefix + secret_bytes + suffix)
class PrivateKeyTest(TestCase):
def test_sign(self):
pk = PrivateKey(randint(0, N))
z = randint(0, 2**256)
sig = pk.sign(z)
self.assertTrue(pk.point.verify(z, sig))
def test_wif(self):
pk = PrivateKey(2**256 - 2**199)
expected = 'L5oLkpV3aqBJ4BgssVAsax1iRa77G5CVYnv9adQ6Z87te7TyUdSC'
self.assertEqual(pk.wif(compressed=True, testnet=False), expected)
pk = PrivateKey(2**256 - 2**201)
expected = '93XfLeifX7Jx7n7ELGMAf1SUR6f9kgQs8Xke8WStMwUtrDucMzn'
self.assertEqual(pk.wif(compressed=False, testnet=True), expected)
pk =
Your preview ends here
Eager to read complete document? Join bartleby learn and gain access to the full version
- Access to all documents
- Unlimited textbook solutions
- 24/7 expert homework help
PrivateKey(0x0dba685b4511dbd3d368e5c4358a1277de9486447af7b3604a69b8d9d8b7889d)
expected = '5HvLFPDVgFZRK9cd4C5jcWki5Skz6fmKqi1GQJf5ZoMofid2Dty'
self.assertEqual(pk.wif(compressed=False, testnet=False), expected)
pk = PrivateKey(0x1cca23de92fd1862fb5b76e5f4f50eb082165e5191e116c18ed1a6b24be6a53f)
expected = 'cNYfWuhDpbNM1JWc3c6JTrtrFVxU4AGhUKgw5f93NP2QaBqmxKkg'
self.assertEqual(pk.wif(compressed=True, testnet=True), expected)
Related Documents
Recommended textbooks for you
Programming Logic & Design Comprehensive
Computer Science
ISBN:9781337669405
Author:FARRELL
Publisher:Cengage
EBK JAVA PROGRAMMING
Computer Science
ISBN:9781337671385
Author:FARRELL
Publisher:CENGAGE LEARNING - CONSIGNMENT
Microsoft Visual C#
Computer Science
ISBN:9781337102100
Author:Joyce, Farrell.
Publisher:Cengage Learning,
C++ Programming: From Problem Analysis to Program...
Computer Science
ISBN:9781337102087
Author:D. S. Malik
Publisher:Cengage Learning
EBK JAVA PROGRAMMING
Computer Science
ISBN:9781305480537
Author:FARRELL
Publisher:CENGAGE LEARNING - CONSIGNMENT
New Perspectives on HTML5, CSS3, and JavaScript
Computer Science
ISBN:9781305503922
Author:Patrick M. Carey
Publisher:Cengage Learning
Recommended textbooks for you
- Programming Logic & Design ComprehensiveComputer ScienceISBN:9781337669405Author:FARRELLPublisher:CengageEBK JAVA PROGRAMMINGComputer ScienceISBN:9781337671385Author:FARRELLPublisher:CENGAGE LEARNING - CONSIGNMENTMicrosoft Visual C#Computer ScienceISBN:9781337102100Author:Joyce, Farrell.Publisher:Cengage Learning,
- C++ Programming: From Problem Analysis to Program...Computer ScienceISBN:9781337102087Author:D. S. MalikPublisher:Cengage LearningEBK JAVA PROGRAMMINGComputer ScienceISBN:9781305480537Author:FARRELLPublisher:CENGAGE LEARNING - CONSIGNMENTNew Perspectives on HTML5, CSS3, and JavaScriptComputer ScienceISBN:9781305503922Author:Patrick M. CareyPublisher:Cengage Learning
Programming Logic & Design Comprehensive
Computer Science
ISBN:9781337669405
Author:FARRELL
Publisher:Cengage
EBK JAVA PROGRAMMING
Computer Science
ISBN:9781337671385
Author:FARRELL
Publisher:CENGAGE LEARNING - CONSIGNMENT
Microsoft Visual C#
Computer Science
ISBN:9781337102100
Author:Joyce, Farrell.
Publisher:Cengage Learning,
C++ Programming: From Problem Analysis to Program...
Computer Science
ISBN:9781337102087
Author:D. S. Malik
Publisher:Cengage Learning
EBK JAVA PROGRAMMING
Computer Science
ISBN:9781305480537
Author:FARRELL
Publisher:CENGAGE LEARNING - CONSIGNMENT
New Perspectives on HTML5, CSS3, and JavaScript
Computer Science
ISBN:9781305503922
Author:Patrick M. Carey
Publisher:Cengage Learning