Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# extract data
fi = ewif_bytes[0:1]
checksum_from_ewif = ewif_bytes[-2:]
ewif_no_checksum = ewif_bytes[0:-2]
salt = ewif_bytes[1:5]
encryptedhalf1 = ewif_bytes[5:21]
encryptedhalf2 = ewif_bytes[21:37]
# check format flag
if fi != b"\x02":
raise Exception("Error: bad format version, not EWIF")
# checksum control
checksum = libnacl.crypto_hash_sha256(
libnacl.crypto_hash_sha256(ewif_no_checksum)
)[0:2]
if checksum_from_ewif != checksum:
raise Exception("Error: bad checksum of the EWIF")
# SCRYPT
password_bytes = password.encode("utf-8")
scrypt_seed = scrypt(password_bytes, salt, 16384, 8, 8, 64)
derivedhalf1 = scrypt_seed[0:32]
derivedhalf2 = scrypt_seed[32:64]
# AES
aes = pyaes.AESModeOfOperationECB(derivedhalf2)
decryptedhalf1 = aes.decrypt(encryptedhalf1)
decryptedhalf2 = aes.decrypt(encryptedhalf2)
# XOR
wif_bytes = Base58Encoder.decode(wif_hex)
if len(wif_bytes) != 35:
raise Exception("Error: the size of WIF is invalid")
# extract data
checksum_from_wif = wif_bytes[-2:]
fi = wif_bytes[0:1]
seed = wif_bytes[1:-2]
seed_fi = wif_bytes[0:-2]
# check WIF format flag
if fi != b"\x01":
raise Exception("Error: bad format version, not WIF")
# checksum control
checksum = libnacl.crypto_hash_sha256(libnacl.crypto_hash_sha256(seed_fi))[0:2]
if checksum_from_wif != checksum:
raise Exception("Error: bad checksum of the WIF")
return cls(seed)
def save_wif_file(self, path: str) -> None:
"""
Save a Wallet Import Format file (WIF) v1
:param path: Path to file
"""
# version
version = 1
# add format to seed (1=WIF,2=EWIF)
seed_fi = b"\x01" + self.seed
# calculate checksum
sha256_v1 = libnacl.crypto_hash_sha256(seed_fi)
sha256_v2 = libnacl.crypto_hash_sha256(sha256_v1)
checksum = sha256_v2[0:2]
# base58 encode key and checksum
wif_key = Base58Encoder.encode(seed_fi + checksum)
with open(path, "w") as fh:
fh.write(
"""Type: WIF
Version: {version}
Data: {data}""".format(
version=version, data=wif_key
)
derivedhalf2 = scrypt_seed[32:64]
# AES
aes = pyaes.AESModeOfOperationECB(derivedhalf2)
decryptedhalf1 = aes.decrypt(encryptedhalf1)
decryptedhalf2 = aes.decrypt(encryptedhalf2)
# XOR
seed1 = xor_bytes(decryptedhalf1, derivedhalf1[0:16])
seed2 = xor_bytes(decryptedhalf2, derivedhalf1[16:32])
seed = bytes(seed1 + seed2)
# Password Control
signer = SigningKey(seed)
salt_from_seed = libnacl.crypto_hash_sha256(
libnacl.crypto_hash_sha256(Base58Encoder.decode(signer.pubkey))
)[0:4]
if salt_from_seed != salt:
raise Exception("Error: bad Password of EWIF address")
return cls(seed)
def get_key_decryption_file(pass_hash, salt):
""" Gets key for decryption """
for _index in range(2, 2 ** 17):
pass_hash = libnacl.crypto_hash_sha512(salt + pass_hash)
return libnacl.crypto_hash_sha256(salt + pass_hash)
derivedhalf1 = scrypt_seed[0:32]
derivedhalf2 = scrypt_seed[32:64]
# AES
aes = pyaes.AESModeOfOperationECB(derivedhalf2)
decryptedhalf1 = aes.decrypt(encryptedhalf1)
decryptedhalf2 = aes.decrypt(encryptedhalf2)
# XOR
seed1 = xor_bytes(decryptedhalf1, derivedhalf1[0:16])
seed2 = xor_bytes(decryptedhalf2, derivedhalf1[16:32])
seed = bytes(seed1 + seed2)
# Password Control
signer = SigningKey(seed)
salt_from_seed = libnacl.crypto_hash_sha256(
libnacl.crypto_hash_sha256(Base58Encoder.decode(signer.pubkey))
)[0:4]
if salt_from_seed != salt:
raise Exception("Error: bad Password of EWIF address")
return cls(seed)
def save_ewif_file(self, path: str, password: str) -> None:
"""
Save an Encrypted Wallet Import Format file (WIF v2)
:param path: Path to file
:param password:
"""
# version
version = 1
# add version to seed
salt = libnacl.crypto_hash_sha256(
libnacl.crypto_hash_sha256(Base58Encoder.decode(self.pubkey))
)[0:4]
# SCRYPT
password_bytes = password.encode("utf-8")
scrypt_seed = scrypt(password_bytes, salt, 16384, 8, 8, 64)
derivedhalf1 = scrypt_seed[0:32]
derivedhalf2 = scrypt_seed[32:64]
# XOR
seed1_xor_derivedhalf1_1 = bytes(xor_bytes(self.seed[0:16], derivedhalf1[0:16]))
seed2_xor_derivedhalf1_2 = bytes(
xor_bytes(self.seed[16:32], derivedhalf1[16:32])
)
# AES
aes = pyaes.AESModeOfOperationECB(derivedhalf2)
def evenCompare(a: str, b: str) -> bool:
"""
A deterministic but more evenly distributed comparator than simple alphabetical.
Useful when comparing consecutive strings and an even distribution is needed.
Provides an even chance of returning true as often as false
"""
ab = a.encode('utf-8')
bb = b.encode('utf-8')
ac = crypto_hash_sha256(ab)
bc = crypto_hash_sha256(bb)
return ac < bc