Пример #1
0
def genesis_commitments(wallets, blind):
    commitments = []
    for pkh_b58, amount in wallets.items():
        # Public key hash corresponding to this Tezos address.
        pkh = base58_decode(pkh_b58.encode('utf-8'))
        # The redemption code is unique to the public key hash and deterministically
        # constructed using a secret blinding value.
        secret = secret_code(pkh, blind)
        # The redemption code is used to blind the pkh
        blinded_pkh = blake2b(pkh, 20, key=secret).digest()
        commitment = {
            'blinded_pkh': base58_encode(blinded_pkh, prefix=b'btz1').decode(),
            'amount': amount
        }
        commitments.append(commitment)
    return commitments
Пример #2
0
    def verify(self, signature: Union[str, bytes],
               message: Union[str, bytes]) -> None:
        """Verify signature, raise exception if it is not valid.

        :param message: sequance of bytes, raw format or hexadecimal notation
        :param signature: a signature in base58 encoding
        :raises: ValueError if signature is not valid
        """
        encoded_signature = scrub_input(signature)
        encoded_message = scrub_input(message)

        if not self.public_point:
            raise ValueError("Cannot verify without a public key")

        if encoded_signature[:3] != b'sig':  # not generic
            if self.curve != encoded_signature[:2]:  # "sp", "p2" "ed"
                raise ValueError("Signature and public key curves mismatch.")

        decoded_signature = base58_decode(encoded_signature)

        # Ed25519
        if self.curve == b"ed":
            digest = pysodium.crypto_generichash(encoded_message)
            try:
                pysodium.crypto_sign_verify_detached(decoded_signature, digest,
                                                     self.public_point)
            except ValueError as exc:
                raise ValueError('Signature is invalid.') from exc
        # Secp256k1
        elif self.curve == b"sp":
            pk = secp256k1.PublicKey(self.public_point, raw=True)
            sig = pk.ecdsa_deserialize_compact(decoded_signature)
            if not pk.ecdsa_verify(encoded_message, sig, digest=blake2b_32):
                raise ValueError('Signature is invalid.')
        # P256
        elif self.curve == b"p2":
            pk = fastecdsa.encoding.sec1.SEC1Encoder.decode_public_key(
                self.public_point, curve=fastecdsa.curve.P256)
            r, s = bytes_to_int(decoded_signature[:32]), bytes_to_int(
                decoded_signature[32:])
            if not fastecdsa.ecdsa.verify(
                    sig=(r, s), msg=encoded_message, Q=pk,
                    hashfunc=blake2b_32):
                raise ValueError('Signature is invalid.')
        else:
            raise Exception(
                f'Unknown elliptic curve {self.curve}')  # type: ignore
Пример #3
0
    def from_encoded_key(cls, key, passphrase=''):
        """ Creates a key object from a base58 encoded key.

        :param key: a public or secret key in base58 encoding
        :param passphrase: the passphrase used if the key provided is an encrypted private key
        """
        key = scrub_input(key)

        curve = key[:2]  # "sp", "p2" "ed"
        if curve not in [b'sp', b'p2', b'ed']:
            raise ValueError("Invalid prefix for a key encoding.")
        if not len(key) in [54, 55, 88, 98]:
            raise ValueError("Invalid length for a key encoding.")

        encrypted = (key[2:3] == b'e')
        public_or_secret = key[3:5] if encrypted else key[2:4]
        if public_or_secret not in [b'pk', b'sk']:
            raise Exception("Invalid prefix for a key encoding.")

        key = base58_decode(key)
        is_secret = (public_or_secret == b'sk')
        if not is_secret:
            return cls.from_public_point(key, curve)

        if encrypted:
            if not passphrase:
                raise ValueError(
                    "Encrypted key provided without a passphrase.")
            if isinstance(passphrase, str):
                passphrase = passphrase.encode()
            assert isinstance(
                passphrase, bytes
            ), f'expected bytes or str, got {type(passphrase).__name__}'

            salt, encrypted_sk = key[:8], key[8:]
            encryption_key = hashlib.pbkdf2_hmac(hash_name="sha512",
                                                 password=passphrase,
                                                 salt=salt,
                                                 iterations=32768,
                                                 dklen=32)
            key = pysodium.crypto_secretbox_open(c=encrypted_sk,
                                                 nonce=b'\000' * 24,
                                                 k=encryption_key)
            del passphrase

        return cls.from_secret_exponent(key, curve)
Пример #4
0
    def from_encoded_key(
        cls,
        key: Union[str, bytes],
        passphrase: PassphraseInput = None,
    ) -> 'Key':
        """Creates a key object from a base58 encoded key.

        :param key: a public or secret key in base58 encoding
        :param passphrase: the passphrase used if the key provided is an encrypted private key,
            if not set value from from PYTEZOS_PASSPHRASE env variable will be used or promted dynamically
        """
        encoded_key = scrub_input(key)

        curve = encoded_key[:2]  # "sp", "p2" "ed"
        if curve not in [b'sp', b'p2', b'ed']:
            raise ValueError("Invalid prefix for a key encoding.")
        if not len(encoded_key) in [54, 55, 88, 98]:
            raise ValueError("Invalid length for a key encoding.")

        encrypted = encoded_key[2:3] == b'e'
        public_or_secret = encoded_key[3:5] if encrypted else encoded_key[2:4]
        if public_or_secret not in [b'pk', b'sk']:
            raise Exception("Invalid prefix for a key encoding.")

        encoded_key = base58_decode(encoded_key)
        is_secret = public_or_secret == b'sk'
        if not is_secret:
            return cls.from_public_point(encoded_key, curve)

        if encrypted:
            passphrase = get_passphrase(passphrase)

            salt, encrypted_sk = encoded_key[:8], encoded_key[8:]
            encryption_key = hashlib.pbkdf2_hmac(hash_name="sha512",
                                                 password=passphrase,
                                                 salt=salt,
                                                 iterations=32768,
                                                 dklen=32)
            encoded_key = pysodium.crypto_secretbox_open(
                c=encrypted_sk,
                nonce=b'\000' * 24,
                k=encryption_key,
            )
            del passphrase

        return cls.from_secret_exponent(encoded_key, curve)
Пример #5
0
    def sign(self) -> 'OperationGroup':
        """Sign the operation group with the key specified by `using`.

        :rtype: OperationGroup
        """
        validation_pass = validation_passes[self.contents[0]['kind']]
        if any(map(lambda x: validation_passes[x['kind']] != validation_pass, self.contents)):
            raise ValueError('Mixed validation passes')

        if validation_pass == 0:
            if self.chain_id is None:
                raise ValueError('Chain ID is undefined, run .fill first')
            watermark = b'\x02' + base58_decode(self.chain_id.encode())
        else:
            watermark = b'\x03'

        message = watermark + bytes.fromhex(self.forge())
        signature = self.key.sign(message=message, generic=True)

        return self._spawn(signature=signature)
Пример #6
0
def forge_base58(value: str) -> bytes:
    """ Encode base58 string into bytes.

    :param value: base58 encoded value (with checksum)
    """
    return base58_decode(value.encode())
Пример #7
0
 def watermark(self):
     """Chain watermark, hex encoded."""
     data = self.chain_id()
     return hexlify(base58_decode(data.encode())).decode()
Пример #8
0
def get_originated_address(index: int, opg_hash=None):
    prefix = base58_decode(opg_hash) if opg_hash else b'\x00' * 32
    nonce = prefix + index.to_bytes(4, 'big')
    nonce_hash = blake2b(data=nonce, digest_size=20).digest()
    return base58_encode(nonce_hash, b'KT1').decode()
Пример #9
0
 def raw(self) -> bytes:
     return base58_decode(self.value.encode())
Пример #10
0
 def test_b58_decode_encode(self, string, prefix):
     data = base58_decode(string)
     result = base58_encode(data, prefix)
     self.assertEqual(string, result)