def get_size(cls, curve: ec.EllipticCurve = None): """ Returns the size (in bytes) of a KFrag given the curve. If no curve is provided, it will use the default curve. """ curve = curve if curve is not None else default_curve() bn_size = CurveBN.get_size(curve) point_size = Point.get_size(curve) return (bn_size * 4) + (point_size * 2)
def get_size(cls, curve: ec.EllipticCurve = None): """ Returns the size (in bytes) of a CorrectnessProof without the metadata. If no curve is given, it will use the default curve. """ curve = curve if curve is not None else default_curve() bn_size = CurveBN.get_size(curve=curve) point_size = Point.get_size(curve=curve) return (bn_size * 3) + (point_size * 4)
def get_size(cls, curve: ec.EllipticCurve = None): """ Returns the size (in bytes) of a CapsuleFrag given the curve without the CorrectnessProof. If no curve is provided, it will use the default curve. """ curve = curve if curve is not None else default_curve() bn_size = CurveBN.get_size(curve) point_size = Point.get_size(curve) return (bn_size * 1) + (point_size * 3)
def from_bytes(cls, data: bytes, curve: ec.EllipticCurve = None): """ Instantiate a KFrag object from the serialized data. """ curve = curve if curve is not None else default_curve() bn_size = CurveBN.get_size(curve) point_size = Point.get_size(curve) data = BytesIO(data) # CurveBNs are the keysize in bytes, Points are compressed and the # keysize + 1 bytes long. id = data.read(bn_size) key = CurveBN.from_bytes(data.read(bn_size), curve) ni = Point.from_bytes(data.read(point_size), curve) commitment = Point.from_bytes(data.read(point_size), curve) xcoord = Point.from_bytes(data.read(point_size), curve) sig1 = CurveBN.from_bytes(data.read(bn_size), curve) sig2 = CurveBN.from_bytes(data.read(bn_size), curve) return cls(id, key, ni, commitment, xcoord, sig1, sig2)
def from_bytes(cls, data: bytes, curve: ec.EllipticCurve = None): """ Instantiates a CapsuleFrag object from the serialized data. """ curve = curve if curve is not None else default_curve() bn_size = CurveBN.get_size(curve=curve) point_size = Point.get_size(curve=curve) data = BytesIO(data) # CurveBNs are the keysize in bytes, Points are compressed and the # keysize + 1 bytes long. e1 = Point.from_bytes(data.read(point_size), curve) v1 = Point.from_bytes(data.read(point_size), curve) kfrag_id = data.read(bn_size) ni = Point.from_bytes(data.read(point_size), curve) xcoord = Point.from_bytes(data.read(point_size), curve) proof = data.read() or None proof = CorrectnessProof.from_bytes(proof, curve) if proof else None return cls(e1, v1, kfrag_id, ni, xcoord, proof)
def from_bytes(cls, data: bytes, curve: ec.EllipticCurve=None): """ Instantiate CorrectnessProof from serialized data. """ curve = curve if curve is not None else default_curve() bn_size = CurveBN.get_size(curve) point_size = Point.get_size(curve) data = BytesIO(data) # CurveBNs are the keysize in bytes, Points are compressed and the # keysize + 1 bytes long. e2 = Point.from_bytes(data.read(point_size), curve) v2 = Point.from_bytes(data.read(point_size), curve) kfrag_commitment = Point.from_bytes(data.read(point_size), curve) kfrag_pok = Point.from_bytes(data.read(point_size), curve) kfrag_sig1 = CurveBN.from_bytes(data.read(bn_size), curve) kfrag_sig2 = CurveBN.from_bytes(data.read(bn_size), curve) sig = CurveBN.from_bytes(data.read(bn_size), curve) metadata = data.read() or None return cls(e2, v2, kfrag_commitment, kfrag_pok, kfrag_sig1, kfrag_sig2, sig, metadata=metadata)
def split_rekey(privkey_a_bn: Union[UmbralPrivateKey, CurveBN], pubkey_b_point: Union[UmbralPublicKey, Point], threshold: int, N: int, params: UmbralParameters=None) -> List[KFrag]: """ Creates a re-encryption key from Alice to Bob and splits it in KFrags, using Shamir's Secret Sharing. Requires a threshold number of KFrags out of N to guarantee correctness of re-encryption. Returns a list of KFrags. """ params = params if params is not None else default_params() g = params.g if isinstance(privkey_a_bn, UmbralPrivateKey): pubkey_a_point = privkey_a_bn.get_pubkey().point_key privkey_a_bn = privkey_a_bn.bn_key else: pubkey_a_point = privkey_a_bn * g if isinstance(pubkey_b_point, UmbralPublicKey): pubkey_b_point = pubkey_b_point.point_key # 'ni' stands for 'Non Interactive'. # This point is used as an ephemeral public key in a DH key exchange, # and the resulting shared secret 'd' allows to make Umbral non-interactive priv_ni = CurveBN.gen_rand(params.curve) ni = priv_ni * g d = CurveBN.hash(ni, pubkey_b_point, pubkey_b_point * priv_ni, params=params) coeffs = [privkey_a_bn * (~d)] coeffs += [CurveBN.gen_rand(params.curve) for _ in range(threshold - 1)] u = params.u # 'xcoord' stands for 'X coordinate'. # This point is used as an ephemeral public key in a DH key exchange, # and the resulting shared secret 'dh_xcoord' contributes to prevent # reconstruction of the re-encryption key without Bob's intervention priv_xcoord = CurveBN.gen_rand(params.curve) xcoord = priv_xcoord * g dh_xcoord = priv_xcoord * pubkey_b_point blake2b = hashes.Hash(hashes.BLAKE2b(64), backend=backend) blake2b.update(xcoord.to_bytes()) blake2b.update(pubkey_b_point.to_bytes()) blake2b.update(dh_xcoord.to_bytes()) hashed_dh_tuple = blake2b.finalize() bn_size = CurveBN.get_size(params.curve) kfrags = [] for _ in range(N): id = os.urandom(bn_size) share_x = CurveBN.hash(id, hashed_dh_tuple, params=params) rk = poly_eval(coeffs, share_x) u1 = rk * u # TODO: change this Schnorr signature for Ed25519 or ECDSA (#97) y = CurveBN.gen_rand(params.curve) g_y = y * g signature_input = (g_y, id, pubkey_a_point, pubkey_b_point, u1, ni, xcoord) z1 = CurveBN.hash(*signature_input, params=params) z2 = y - privkey_a_bn * z1 kfrag = KFrag(id=id, bn_key=rk, point_noninteractive=ni, point_commitment=u1, point_xcoord=xcoord, bn_sig1=z1, bn_sig2=z2) kfrags.append(kfrag) return kfrags