def OPRF(x: str, point: ecc.Point) -> bytearray: '''Performs the actual Hash H of H(x, (H'(X))^d), which is the hash of a bytearray x and a Point on the curve. Returns a bytearray result. ''' H = sha256() H.update(x.encode()) H.update(I2OSP(point.x(), 256)) H.update(I2OSP(point.y(), 256)) return H.digest()
def clientToPassword(beta: ecc.Point) -> str: '''input the point on the curve. If it is in the Group, we compute this point exponeniated to the inverse of rho, and then we use the OPRF to create the byte array which generates the final password rwd ''' if curve_256.contains_point(beta.x(), beta.y()) != True: raise ValueError("Point {} does not exist on curve {}".format(beta, curve_256)) final = beta * pow(rho, ORDER-2, ORDER) rwdbytes = OPRF(x, final) return gen_password(rwdbytes)
def deviceToClient(alpha: ecc.Point, index: int=1) -> ecc.Point: '''input the point on the curve. If it is in the Group, we store a random key D that corresponds to this point, and return the point exponeniated to D. ''' if curve_256.contains_point(alpha.x(), alpha.y()) != True: raise ValueError("Point {} does not exist on curve {}".format(alpha, curve_256)) randomBytes = os.urandom(32) d = HashToBase(randomBytes, index) print("DEVICE: I am going to store d: ", d) return d * alpha, d # beta = alpha^d
def serialize_curve_point(p: Point) -> bytes: """ Serialize an elliptic curve point ``p`` in compressed form as described in SEC1v2 (https://secg.org/sec1-v2.pdf) section 2.3.3. Corresponds directly to the "ser_P(P)" function in BIP32 (https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#conventions). :param p: The elliptic curve point to be serialized. :return: A byte sequence containing the serialization of ``p``. """ x, y = p.x(), p.y() if y & 1: return b'\x03' + serialize_uint256(x) else: return b'\x02' + serialize_uint256(x)
def __uncompress_public_key(public_key: bytes) -> bytes: """ Uncompress the compressed public key. :param public_key: compressed public key :return: uncompressed public key """ is_even = public_key.startswith(b'\x02') x = string_to_number(public_key[1:]) curve = NIST256p.curve order = NIST256p.order p = curve.p() alpha = (pow(x, 3, p) + (curve.a() * x) + curve.b()) % p beta = square_root_mod_prime(alpha, p) if is_even == bool(beta & 1): y = p - beta else: y = beta point = Point(curve, x, y, order) return b''.join([number_to_string(point.x(), order), number_to_string(point.y(), order)])
def point_to_pubkey(point: Point) -> bytes: order = SECP256k1.order x_str = number_to_string(point.x(), order) y_str = number_to_string(point.y(), order) vk = x_str + y_str return struct.pack("B", (vk[63] & 1) + 2) + vk[0:32] # To compressed key
def point_to_pubkey_bytes(point: Point): result = bytearray(bytes.fromhex(hex(point.x())[2:])) result.extend(bytearray(bytes.fromhex(hex(point.y())[2:]))) return result