def __init__( self, signature_bytes: bytes = None, vrs: Tuple[int, int, int] = None, backend: 'Union[BaseECCBackend, Type[BaseECCBackend], str, None]' = None, ) -> None: if bool(signature_bytes) is bool(vrs): raise TypeError( "You must provide one of `signature_bytes` or `vrs`") elif signature_bytes: validate_recoverable_signature_bytes(signature_bytes) r = big_endian_to_int(signature_bytes[0:32]) s = big_endian_to_int(signature_bytes[32:64]) v = ord(signature_bytes[64:65]) elif vrs: v, r, s, = vrs else: raise TypeError("Invariant: unreachable code path") super().__init__(rs=(r, s), backend=backend) try: self.v = v except ValidationError as error: raise BadSignature(str(error)) from error
def compress_public_key_bytes(self, uncompressed_public_key_bytes: bytes) -> bytes: validate_uncompressed_public_key_bytes(uncompressed_public_key_bytes) point = ( big_endian_to_int(uncompressed_public_key_bytes[:32]), big_endian_to_int(uncompressed_public_key_bytes[32:]), ) public_key = self.keys.PublicKey.from_point(*point) return public_key.format(compressed=True)
def ecdsa_raw_sign(msg_hash: bytes, private_key_bytes: bytes) -> Tuple[int, int, int]: z = big_endian_to_int(msg_hash) k = deterministic_generate_k(msg_hash, private_key_bytes) r, y = fast_multiply(G, k) s_raw = inv(k, N) * (z + r * big_endian_to_int(private_key_bytes)) % N v = 27 + ((y % 2) ^ (0 if s_raw * 2 < N else 1)) s = s_raw if s_raw * 2 < N else N - s_raw return v - 27, r, s
def ecdsa_raw_recover(msg_hash: bytes, vrs: Tuple[int, int, int]) -> bytes: v, r, s = vrs v += 27 if not (27 <= v <= 34): raise BadSignature("%d must in range 27-31" % v) x = r xcubedaxb = (x * x * x + A * x + B) % P beta = pow(xcubedaxb, (P + 1) // 4, P) y = beta if v % 2 ^ beta % 2 else (P - beta) # If xcubedaxb is not a quadratic residue, then r cannot be the x coord # for a point on the curve, and so the sig is invalid if (xcubedaxb - y * y) % P != 0 or not (r % N) or not (s % N): raise BadSignature("Invalid signature") z = big_endian_to_int(msg_hash) Gz = jacobian_multiply((Gx, Gy, 1), (N - z) % N) XY = jacobian_multiply((x, y, 1), s) Qr = jacobian_add(Gz, XY) Q = jacobian_multiply(Qr, inv(r, N)) raw_public_key = from_jacobian(Q) return encode_raw_public_key(raw_public_key)
def _decode_keyfile_json_v3(keyfile_json, password): crypto = keyfile_json['crypto'] kdf = crypto['kdf'] # Derive the encryption key from the password using the key derivation # function. if kdf == 'pbkdf2': derived_key = _derive_pbkdf_key(crypto, password) elif kdf == 'scrypt': derived_key = _derive_scrypt_key(crypto, password) else: raise TypeError("Unsupported key derivation function: {0}".format(kdf)) # Validate that the derived key matchs the provided MAC ciphertext = decode_hex(crypto['ciphertext']) mac = keccak(derived_key[16:32] + ciphertext) expected_mac = decode_hex(crypto['mac']) if not hmac.compare_digest(mac, expected_mac): raise ValueError("MAC mismatch") # Decrypt the ciphertext using the derived encryption key to get the # private key. encrypt_key = derived_key[:16] cipherparams = crypto['cipherparams'] iv = big_endian_to_int(decode_hex(cipherparams['iv'])) private_key = decrypt_aes_ctr(ciphertext, encrypt_key, iv) return private_key
def _create_v3_keyfile_json(hrp,private_key, password, kdf, work_factor=None, salt_size=16): salt = Random.get_random_bytes(salt_size) if work_factor is None: work_factor = get_default_work_factor_for_kdf(kdf) if kdf == 'pbkdf2': derived_key = _pbkdf2_hash( password, hash_name='sha256', salt=salt, iterations=work_factor, dklen=DKLEN, ) kdfparams = { 'c': work_factor, 'dklen': DKLEN, 'prf': 'hmac-sha256', 'salt': encode_hex_no_prefix(salt), } elif kdf == 'scrypt': derived_key = _scrypt_hash( password, salt=salt, buflen=DKLEN, r=SCRYPT_R, p=SCRYPT_P, n=work_factor, ) kdfparams = { 'dklen': DKLEN, 'n': work_factor, 'r': SCRYPT_R, 'p': SCRYPT_P, 'salt': encode_hex_no_prefix(salt), } else: raise NotImplementedError("KDF not implemented: {0}".format(kdf)) iv = big_endian_to_int(Random.get_random_bytes(16)) encrypt_key = derived_key[:16] ciphertext = encrypt_aes_ctr(private_key, encrypt_key, iv) mac = keccak(derived_key[16:32] + ciphertext) pub = keys.PrivateKey(private_key).public_key return { 'address': pub.to_bech32_address(hrp), 'crypto': { 'cipher': 'aes-128-ctr', 'cipherparams': { 'iv': encode_hex_no_prefix(int_to_big_endian(iv)), }, 'ciphertext': encode_hex_no_prefix(ciphertext), 'kdf': kdf, 'kdfparams': kdfparams, 'mac': encode_hex_no_prefix(mac), }, 'id': str(uuid.uuid4()), 'version': 3, }
def decoder_fn(self, data): value = big_endian_to_int(data) with decimal.localcontext(abi_decimal_context): decimal_value = decimal.Decimal(value) / TEN**self.frac_places return decimal_value
def __init__(self, signature_bytes: bytes = None, rs: Tuple[int, int] = None, backend: 'Union[BaseECCBackend, Type[BaseECCBackend], str, None]' = None, ) -> None: if signature_bytes is None and rs is None: raise TypeError("You must provide one of `signature_bytes` or `vr`") elif signature_bytes: validate_non_recoverable_signature_bytes(signature_bytes) r = big_endian_to_int(signature_bytes[0:32]) s = big_endian_to_int(signature_bytes[32:64]) elif rs: r, s = rs else: raise Exception("Invariant: unreachable code path") super().__init__(rs=(r, s), backend=backend)
def private_key_to_public_key(private_key_bytes: bytes) -> bytes: private_key_as_num = big_endian_to_int(private_key_bytes) if private_key_as_num >= N: raise Exception("Invalid privkey") raw_public_key = fast_multiply(G, private_key_as_num) public_key_bytes = encode_raw_public_key(raw_public_key) return public_key_bytes
def decoder_fn(self, data): value = big_endian_to_int(data) with decimal.localcontext(abi_decimal_context): decimal_value = decimal.Decimal(value) raw_real_value = decimal_value / 2**self.low_bit_size real_value = quantize_value(raw_real_value, self.low_bit_size) return real_value
def decoder_fn(self, data): value = big_endian_to_int(data) if value >= 2**(self.value_bit_size - 1): signed_value = value - 2**self.value_bit_size else: signed_value = value with decimal.localcontext(abi_decimal_context): decimal_value = decimal.Decimal( signed_value) / TEN**self.frac_places return decimal_value
def deterministic_generate_k(msg_hash: bytes, private_key_bytes: bytes, digest_fn: Callable[[], Any] = hashlib.sha256) -> int: v_0 = b'\x01' * 32 k_0 = b'\x00' * 32 k_1 = hmac.new(k_0, v_0 + b'\x00' + private_key_bytes + msg_hash, digest_fn).digest() v_1 = hmac.new(k_1, v_0, digest_fn).digest() k_2 = hmac.new(k_1, v_1 + b'\x01' + private_key_bytes + msg_hash, digest_fn).digest() v_2 = hmac.new(k_2, v_1, digest_fn).digest() kb = hmac.new(k_2, v_2, digest_fn).digest() k = big_endian_to_int(kb) return k
def decoder_fn(self, data): value = big_endian_to_int(data) if value >= 2**(self.high_bit_size + self.low_bit_size - 1): signed_value = value - 2**(self.high_bit_size + self.low_bit_size) else: signed_value = value with decimal.localcontext(abi_decimal_context): signed_decimal_value = decimal.Decimal(signed_value) raw_real_value = signed_decimal_value / 2**self.low_bit_size real_value = quantize_value(raw_real_value, self.low_bit_size) return real_value
def ecdsa_raw_verify(msg_hash: bytes, rs: Tuple[int, int], public_key_bytes: bytes) -> bool: raw_public_key = decode_public_key(public_key_bytes) r, s = rs w = inv(s, N) z = big_endian_to_int(msg_hash) u1, u2 = z * w % N, r * w % N x, y = fast_add( fast_multiply(G, u1), fast_multiply(raw_public_key, u2), ) return bool(r == x and (r % N) and (s % N))
def decompress_public_key(compressed_public_key_bytes: bytes) -> bytes: if len(compressed_public_key_bytes) != 33: raise ValueError("Invalid compressed public key") prefix = compressed_public_key_bytes[0] if prefix not in (2, 3): raise ValueError("Invalid compressed public key") x = big_endian_to_int(compressed_public_key_bytes[1:]) y_squared = (x**3 + A * x + B) % P y_abs = pow(y_squared, ((P + 1) // 4), P) if (prefix == 2 and y_abs & 1 == 1) or (prefix == 3 and y_abs & 1 == 0): y = (-y_abs) % P else: y = y_abs return encode_raw_public_key((x, y))
def to_int(value=None, hexstr=None, text=None): """ Converts value to it's integer representation. Values are converted this way: * value: * bytes: big-endian integer * bool: True => 1, False => 0 * hexstr: interpret hex as integer * text: interpret as string of digits, like '12' => 12 """ assert_one_val(value, hexstr=hexstr, text=text) if hexstr is not None: return int(hexstr, 16) elif text is not None: return int(text) elif isinstance(value, bytes): return big_endian_to_int(value) elif isinstance(value, str): raise TypeError("Pass in strings with keyword hexstr or text") else: return int(value)
def decoder_fn(self, data): value = big_endian_to_int(data) if value >= 2**(self.value_bit_size - 1): return value - 2**self.value_bit_size else: return value
def decode_public_key(public_key_bytes: bytes) -> Tuple[int, int]: left = big_endian_to_int(public_key_bytes[0:32]) right = big_endian_to_int(public_key_bytes[32:64]) return left, right
def __int__(self) -> int: return big_endian_to_int(self._raw_key)
def __int__(self) -> int: return big_endian_to_int(self.to_bytes())
def __hash__(self) -> int: return big_endian_to_int(keccak(self.to_bytes()))