Example #1
0
    def split_rekey(
            self, pubkey: bytes, min_shares: int,
            num_shares: int) -> List[Tuple[tuple, Tuple[bytes, bytes]]]:
        priv_eph = self.pre.gen_priv()
        rks = self.pre.split_rekey(self._priv_key, priv_eph, min_shares,
                                   num_shares)
        encrypted_eph = self.encrypt(ec.serialize(priv_eph), pubkey=pubkey)

        return [((rk.id, ec.serialize(rk.key)), encrypted_eph) for rk in rks]
Example #2
0
 def rekey(self, pubkey: bytes) -> Tuple[tuple, Tuple[bytes, bytes]]:
     """
     Create re-encryption key from private key which we have to public key
     pubkey.
     Internally, we create an ephemeral key priv_eph randomly and share data
     with it, and also attach encrypted priv_eph as the second part of the
     tuple
     """
     priv_eph = self.pre.gen_priv()
     rk = self.pre.rekey(self._priv_key, priv_eph)
     encrypted_eph = self.encrypt(ec.serialize(priv_eph), pubkey=pubkey)
     return ((rk.id, ec.serialize(rk.key)), encrypted_eph)
Example #3
0
    def setUp(self):
        self.pre = umbral.PRE()
        self.privkey_a = self.pre.gen_priv()
        self.privkey_a_bytes = ec.serialize(self.privkey_a)[1:]

        self.privkey_b = self.pre.gen_priv()
        self.privkey_b_bytes = ec.serialize(self.privkey_b)[1:]

        self.pubkey_a = self.pre.priv2pub(self.privkey_a)
        self.pubkey_b = self.pre.priv2pub(self.privkey_b)

        self.pubkey_a_bytes = ec.serialize(self.pubkey_a)[1:]
        self.pubkey_b_bytes = ec.serialize(self.pubkey_b)[1:]
Example #4
0
    def reencrypt(
        self, rekey: Tuple[tuple, Tuple[bytes,
                                        bytes]], ciphertext: Tuple[bytes,
                                                                   bytes]
    ) -> Tuple[Tuple[bytes, bytes], Tuple[bytes, bytes]]:
        """
        Re-encrypt for public key
        rekey is (rk, encrypted_eph), same as output of rekey()
        ciphertext is a tuple in the same format as output of encrypt()

        Output is two tuples: data encrypted with an ephemeral key
        and the ephemeral private key encrypted for recepient (Bob)
        """
        rk, encrypted_eph = rekey
        rk = umbral.RekeyFrag(rk[0],
                              ec.deserialize(self.pre.ecgroup, rk[1]),
                              pre=PRE)
        ekey, edata = ciphertext
        ekey = umbral.EncryptedKey(ekey=ec.deserialize(self.pre.ecgroup,
                                                       ekey[0]),
                                   re_id=ekey[1])

        ekey = self.pre.reencrypt(rk, ekey)

        ekey = (ec.serialize(ekey.ekey), ekey.re_id)
        return (ekey, edata), encrypted_eph
Example #5
0
 def reencrypt(self, rk, emsg):
     if type(emsg) is str:
         emsg = emsg.encode()
     rk = self.load_key(rk)
     emsg = msgpack.loads(emsg)
     c1 = self.load_key(emsg[0])
     c1 = c1**rk
     return msgpack.dumps([ec.serialize(c1)] + emsg[1:])
Example #6
0
    def kdf(self, ecdata, key_length):
        # XXX length
        ecdata = ec.serialize(ecdata)[1:]  # Remove the first (type) bit

        # TODO: Handle salt somehow
        return HKDF(algorithm=hashes.SHA512(),
                    length=key_length,
                    salt=None,
                    info=None,
                    backend=default_backend()).derive(ecdata)
Example #7
0
    def test_pub_bytes2ec(self):
        pubkey = self.pre.priv2pub(self.privkey_a)
        self.assertEqual(ec.ec_element, type(pubkey))

        pubkey_bytes = ec.serialize(pubkey)[1:]
        self.assertEqual(bytes, type(pubkey_bytes))
        self.assertEqual(33, len(pubkey_bytes))

        pubkey_ec = api.pub_bytes2ec(pubkey_bytes)
        self.assertEqual(ec.ec_element, type(pubkey_ec))
        self.assertEqual(pubkey_ec, pubkey)
Example #8
0
def ecies_gen_priv(
        to_bytes: bool = True) -> Union[bytes, elliptic_curve.ec_element]:
    """
    Generates an ECIES private key.

    :param to_bytes: Return the byte serialization of the privkey?

    :return: An ECIES private key
    """
    privkey = PRE.gen_priv()
    if to_bytes:
        return elliptic_curve.serialize(privkey)[1:]
    return privkey
    def combine(self,
                shares: Tuple[Tuple[bytes, bytes], Tuple[bytes, bytes]]
                ) -> Tuple[Tuple[bytes, bytes], Tuple[bytes, bytes]]:
        ekeys = [umbral.EncryptedKey(
                    ekey=ec.deserialize(self.pre.ecgroup, share[0][0][0]),
                    re_id=share[0][0][1])
                 for share in shares]
        ekey = self.pre.combine(ekeys)
        ekey = (ec.serialize(ekey.ekey), ekey.re_id)

        # Everything except ekey is the same for all shares!
        # TODO instead of trusting the first share, trust the majority
        return (ekey, shares[0][0][1]), shares[0][1]
Example #10
0
    def priv2pub(self, priv: Union[bytes, 'elliptic_curve.Element']):
        """
        Takes priv, a secret bytes or elliptic_curve.Element object to be used as a private key.
        Derives a matching public key and returns it.

        Returns a public key matching the type of priv.
        """
        if type(priv) is bytes:
            # If priv is a bytes object, we need to "deserialize" it to an Element first,
            # then raise g to its power, then "reserialize" it to bytes.
            priv = ec.deserialize(self.ecgroup, priv)
            pub = self.g**priv
            return ec.serialize(pub)
        else:
            pub = self.g**priv
            return pub
Example #11
0
 def encrypt(self, pub, msg, padding=True):
     if type(msg) is str:
         msg = msg.encode()
     if padding:
         msg = pad(self.bitsize, msg)
         chunks = [
             msg[i * self.bitsize:i * self.bitsize + self.bitsize]
             for i in range(len(msg) // self.bitsize)
         ]
     else:
         chunks = [msg]
     r = ec.random(self.ecgroup, ec.ZR)
     c1 = self.load_key(pub)**r
     c2 = [(self.g**r) * ec.encode(self.ecgroup, m, False) for m in chunks]
     c2 = map(ec.serialize, c2)
     return msgpack.dumps([ec.serialize(c1)] + list(c2))
Example #12
0
    def test_priv_bytes2ec(self):
        full_privkey_bytes = ec.serialize(self.privkey_a)
        privkey_bytes = full_privkey_bytes[1:]

        if len(privkey_bytes) is not 32:
            # Debug information here.
            print(
                "Hey everybody!  Here's the weird len31 bug.  The bytes were {}."
                .format(full_privkey_bytes))

        self.assertEqual(bytes, type(privkey_bytes))
        self.assertEqual(32, len(privkey_bytes))

        privkey = api.priv_bytes2ec(privkey_bytes)
        self.assertEqual(ec.ec_element, type(privkey))
        self.assertEqual(self.privkey_a, privkey)
Example #13
0
def ecies_priv2pub(
        privkey: Union[bytes, elliptic_curve.ec_element],
        to_bytes: bool = True) -> Union[bytes, elliptic_curve.ec_element]:
    """
    Takes a private key (secret bytes or an elliptic_curve.ec_element) and
    derives the Public key from it.

    :param privkey: The Private key to derive the public key from
    :param to_bytes: Return the byte serialization of the pubkey?

    :return: The Public component of the Private key provided
    """
    if type(privkey) == bytes:
        privkey = priv_bytes2ec(privkey)

    pubkey = PRE.priv2pub(privkey)
    if to_bytes:
        return elliptic_curve.serialize(pubkey)[1:]
    return pubkey
Example #14
0
def ecies_rekey(privkey_a: Union[bytes, elliptic_curve.ec_element],
                privkey_b: Union[bytes, elliptic_curve.ec_element],
                to_bytes: bool = True) -> Union[bytes, umbral.RekeyFrag]:
    """
    Generates a re-encryption key from privkey_a to privkey_b.

    :param privkey_a: Private key to re-encrypt from
    :param privkey_b: Private key to re-encrypt to
    :param to_bytes: Format result as bytes?

    :return: Re-encryption key
    """
    if type(privkey_a) == bytes:
        privkey_a = priv_bytes2ec(privkey_a)
    if type(privkey_b) == bytes:
        privkey_b = priv_bytes2ec(privkey_b)

    rk = PRE.rekey(privkey_a, privkey_b)
    if to_bytes:
        return elliptic_curve.serialize(rk.key)[1:]
    return rk
Example #15
0
    def encrypt(self,
                data: bytes,
                pubkey: bytes = None) -> Tuple[bytes, bytes]:
        """
        :data:      The data to encrypt. If derived per-subpath, it's a
                    symmetric key to use for block ciphers.
        :pubkey:    Optional public key to encrypt for. If not given, encrypt
                    for ours

        :returns:   (ekey, edata) where ekey is needed for recepient to
                    reconstruct a DH secret, edata is data encrypted with this
                    DH secret. The output should be treated as a monolithic
                    ciphertext outside of this class
        """
        if pubkey is None:
            pubkey = self._pub_key
        else:
            pubkey = ec.deserialize(self.pre.ecgroup, pubkey)

        key, ekey = self.pre.encapsulate(pubkey)
        cipher = SecretBox(key)

        return ((ec.serialize(ekey.ekey), None), cipher.encrypt(data))
 def get_param(self):
     return ec.serialize(self.pre.g)
Example #17
0
 def save_key(self, key):
     # Same as in BBS98
     return ec.serialize(key)
Example #18
0
 def pub_key(self):
     return ec.serialize(self._pub_key)
Example #19
0
 def __bytes__(self):
     return ec.serialize(self.id) + ec.serialize(self.key)
Example #20
0
 def save_key(self, key):
     return ec.serialize(key)
Example #21
0
 def to_dict(self):
     return {'g': ec.serialize(self.g), 'curve': self.curve}
Example #22
0
 def gen_priv(self, dtype='ec'):
     priv = ec.random(self.ecgroup, ec.ZR)
     if dtype in ('bytes', bytes):
         return ec.serialize(priv)
     else:
         return priv