示例#1
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
示例#2
0
    def decrypt(self,
                edata: Tuple[bytes, bytes],
                privkey: bytes = None) -> bytes:
        """
        Decrypt data encrypted by ECIES
        edata = (ekey, edata)
            ekey is needed to reconstruct a DH secret
            edata encrypted by the block cipher
            privkey is optional private key if we want to use something else
            than what keypair uses
        """
        if isinstance(edata[0], tuple) and isinstance(edata[1], tuple):
            # In case it was re-encrypted data
            return self.decrypt_reencrypted(edata)

        ekey, edata = edata
        # When it comes to decrypt(), ekey[1] is always None
        # we could use that and save 2 bytes,
        # but it makes the code less readable
        ekey = umbral.EncryptedKey(ekey=ec.deserialize(API.PRE.ecgroup,
                                                       ekey[0]),
                                   re_id=ekey[1])
        if privkey is None:
            privkey = self._priv_key
        else:
            privkey = ec.deserialize(API.PRE.ecgroup, privkey)

        key = self.pre.decapsulate(privkey, ekey)
        cipher = SecretBox(key)
        return cipher.decrypt(edata)
示例#3
0
 def from_bytes(cls, kfrag_bytes, pre=None):
     pre = pre or cls._pre
     return RekeyFrag(
         id=ec.deserialize(pre.ecgroup,
                           kfrag_bytes[:len(kfrag_bytes) // 2]),
         key=ec.deserialize(pre.ecgroup,
                            kfrag_bytes[len(kfrag_bytes) // 2:]),
         pre=pre)
 def encapsulate(self, pubkey: bytes = None):
     if pubkey is None:
         pubkey = self._pub_key
     else:
         pubkey = ec.deserialize(self.pre.ecgroup, pubkey)
     key, ekey = self.pre.encapsulate(pubkey)
     return (key, ekey)
示例#5
0
 def __init__(self, curve=curves.secp256k1, g=None):
     self.curve = curves.secp256k1
     self.ecgroup = ec.elliptic_curve(nid=self.curve)
     if g is None:
         self.g = ec.random(self.ecgroup, ec.G)
     else:
         self.g = ec.deserialize(self.ecgroup, g)
     self.bitsize = ec.bitsize(self.ecgroup)
示例#6
0
def pub_bytes2ec(pubkey: bytes, ) -> elliptic_curve.ec_element:
    """
    Turns a public key, in bytes, into an elliptic_curve.ec_element.

    :param pubkey: Public key to turn into an elliptic_curve.ec_element.

    :return: elliptic_curve.ec_element
    """
    return elliptic_curve.deserialize(PRE.ecgroup, b'\x01' + pubkey)
示例#7
0
def priv_bytes2ec(privkey: bytes) -> elliptic_curve.ec_element:
    """
    Turns a private key, in bytes, into an elliptic_curve.ec_element.

    :param privkey: Private key to turn into an elliptic_curve.ec_element.

    :return: elliptic_curve.ec_element
    """
    return elliptic_curve.deserialize(PRE.ecgroup, b'\x00' + privkey)
示例#8
0
    def __init__(self, curve=curves.secp256k1, g=None):
        self.curve = curve
        self.ecgroup = ec.elliptic_curve(nid=self.curve)

        if g is None:
            self.g = ec.getGenerator(self.ecgroup)
        else:
            if isinstance(g, ec.ec_element):
                self.g = g
            else:
                self.g = ec.deserialize(self.ecgroup, g)

        self.bitsize = ec.bitsize(self.ecgroup)
    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]
示例#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
示例#11
0
    def __init__(self, privkey: bytes = None) -> None:
        """
        :privkey: Optional private key in a serialized form (32-byte string)
                  If not given, a random one is generated.
        """
        # Creating PRE object is slow
        # so let's reuse it per-thread
        if not _tl.pre:
            _tl.pre = umbral.PRE()
        self.pre = _tl.pre

        if not privkey:
            self._priv_key = self.pre.gen_priv()
        else:
            self._priv_key = ec.deserialize(self.pre.ecgroup,
                                            b'\x00' + privkey)

        # We don't always need a public key, so let's make it lazily
        self.__pub_key = None
示例#12
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))
示例#13
0
 def load_key(self, key):
     # Same as in BBS98
     if type(key) is bytes:
         return ec.deserialize(self.ecgroup, key)
     else:
         return key