Ejemplo n.º 1
0
def derive_key_pair(seed: Seed) -> t.Tuple[PrivateKey, PublicKey]:
    private_key = hashes.sha512half(seed)
    public_key = nacl.signing.SigningKey(private_key).verify_key._key[:32]  # pylint: disable=protected-access
    return (
        t.cast(PrivateKey, private_key),
        t.cast(PublicKey, KEY_PREFIX + public_key),
    )
Ejemplo n.º 2
0
def derive_private_key(seed: bytes) -> int:
    sequence = 0
    while True:
        buffer = seed + to_bytes(sequence, 4)
        private_key = from_bytes(hashes.sha512half(buffer))
        if private_key != 0 and private_key < GROUP_ORDER:
            return private_key
        sequence += 1
Ejemplo n.º 3
0
 def sign_transaction(self, transaction: Transaction) -> SignedTransaction:
     result = {
         **transaction, 'SigningPubKey': self.public_key.hex().upper()
     }
     blob = serialize_transaction(result, signing=True)
     signature = self.sign(PREFIX_TRANSACTION_SIGNATURE + blob)
     result['TxnSignature'] = signature.hex().upper()
     blob = serialize_transaction(result)
     digest = sha512half(PREFIX_TRANSACTION_ID + blob)
     result['hash'] = digest.hex().upper()
     return result
Ejemplo n.º 4
0
def verify(message: bytes, signature: Signature, public_key: PublicKey) -> bool:
    digest = hashes.sha512half(message)
    # We need `ecdsa` to decompress the public key.
    # Would be nice if fastecdsa could do this.
    # TODO: Implement it ourselves.
    # https://github.com/AntonKueltz/fastecdsa/issues/47
    verifying_key = VerifyingKey.from_string(public_key, curves.SECP256k1)
    return verifying_key.verify(
        signature,
        digest,
        hashfunc=hashes.IdentityHash,
        sigdecode=sigdecode_der,
    )
Ejemplo n.º 5
0
def sign(message: bytes, private_key: PrivateKey) -> Signature:
    digest = hashes.sha512half(message)
    signing_key = int.from_bytes(private_key, byteorder='big')
    r, s = ecdsa.sign(
        digest.hex(),
        signing_key,
        curve=curve.secp256k1,
        prehashed=True,
    )
    # Both (r, s) and (r, -s mod G = G - s) are valid, canonical signatures.
    # (r, s) is fully canonical only when s <= G - s.
    s_inverse = GROUP_ORDER - s
    if s > s_inverse:
        s = s_inverse
    signature = DEREncoder.encode_signature(r, s)
    return t.cast(Signature, signature)
Ejemplo n.º 6
0
def test_hash_transaction(transaction, blob_hex):
    if 'hash' not in transaction:
        return
    blob = serialization.PREFIX_TRANSACTION_ID + bytes.fromhex(blob_hex)
    digest = hashes.sha512half(blob)
    assert digest.hex().upper() == transaction['hash']
Ejemplo n.º 7
0
def test_sha512half():
    """Just a sanity check that we get the same result."""
    message = b'test message'
    stdlib = hashlib.sha512(message).digest()[:32]
    nacl = hashes.sha512half(message)
    assert stdlib == nacl
Ejemplo n.º 8
0
 def digest(self) -> bytes:
     return hashes.sha512half(self.data)