Sign a Message
After storing a private key in Zyllion, anyone with permissions can use SecretSigner to sign messages or transactions with it. During signing:
The message to be signed and key's store id are provided
The message is hashed before being sent to the network
SecretSigner creates an ECDSA signature using the stored key shares
The signature is returned for use with other applications
When signing a message, only the message hash is sent to the network - the original message stays private.
Usage
Python Client
TypeScript Client
Python Client
Install Zyllion Python Client
pip install zyllion-client
Python Client: Sign a Message
signWithStoredPrivateKey.py
zyllion_config.py
zyllion_constants.py
.env
zylvm/secretsigner-python/signWithStoredPrivateKey.py
from zyllion_client import (
InputPartyBinding,
Network,
ZylChainPayer,
ZylChainPrivateKey,
OutputPartyBinding,
VmClient,
PrivateKey,
EcdsaDigestMessage
)
from zyllion_client.ids import UUID
import asyncio
import hashlib
from zyllion_config import config
from zyllion_signature_constants import TECDSA_DIGEST_NAME, TECDSA_DIGEST_PARTY, TECDSA_KEY_PARTY, TECDSA_OUTPUT_PARTY, TECDSA_PROGRAM_ID
from helpers import verify_signature
# REPLACE THIS WITH YOUR STORE ID
store_id = "af9baa72-ad9f-41d1-879d-df287a6ea11e"
message_to_sign = "Hello, world!"
public_key_for_verification = "0463c7b5356003fd4b188634721487d96c5af82b5038bf884e0da9640bf8206130607c1d0a30432d57793d466e25276bc75dc52a55b26e77486f2dd00e64760bc3"
async def signWithStoredPrivateKey(store_id_to_sign_with: str, message_to_sign: str, public_key: str):
print(f"Connected to zyllion {config.ZYLLION_NETWORK_CONFIG}")
network = Network(
chain_id=config.ZYLLION_ZYLCHAIN_CHAIN_ID,
chain_grpc_endpoint=config.ZYLLION_ZYLCHAIN_GRPC,
zylvm_grpc_endpoint=config.ZYLLION_ZYLVM_GRPC_ENDPOINT,
)
# Create zylChain payer to pay for operations
zylchain_key: str = config.ZYLLION_ZYLCHAIN_PRIVATE_KEY
payer = ZylChainPayer(
network,
wallet_private_key=ZylChainPrivateKey(bytes.fromhex(zylchain_key)),
gas_limit=10000000,
)
# Create a Zyllion Client with a user key
user_key = PrivateKey(hashlib.sha256(config.ZYLLION_USER_KEY_SEED.encode()).digest())
client = await VmClient.create(user_key, network, payer)
# Fund client with UZYL
uzyl_amount_to_add = 10000000
await client.add_funds(uzyl_amount_to_add)
if isinstance(store_id_to_sign_with, str):
store_id = UUID(store_id_to_sign_with)
message_hashed = hashlib.sha256(message_to_sign.encode()).digest()
# Set up the signing computation
input_bindings = [
InputPartyBinding(TECDSA_KEY_PARTY, client.user_id),
InputPartyBinding(TECDSA_DIGEST_PARTY, client.user_id)
]
output_bindings = [OutputPartyBinding(TECDSA_OUTPUT_PARTY, [client.user_id])]
# Execute the signing computation
compute_id = await client.compute(
TECDSA_PROGRAM_ID,
input_bindings,
output_bindings,
values={TECDSA_DIGEST_NAME: EcdsaDigestMessage(bytearray(message_hashed))},
value_ids=[store_id],
).invoke()
# Get the signature
tecdsa_result = await client.retrieve_compute_results(compute_id).invoke()
signature = tecdsa_result["tecdsa_signature"]
# Convert signature to standard format
(r, s) = signature.value
signature_dict = {
'r': hex(int.from_bytes(r, byteorder="big"))[2:], # Remove '0x' prefix
's': hex(int.from_bytes(s, byteorder="big"))[2:] # Remove '0x' prefix
}
print(f"Signature: {signature_dict}")
# Verify the signature
verification_result = verify_signature(message_to_sign, signature_dict, public_key_for_verification)
print(f"Signature verification result: {verification_result}")
if __name__ == "__main__":
asyncio.run(signWithStoredPrivateKey(store_id, message_to_sign, public_key_for_verification))
Signature Verification
Anyone can verify the signature using the same message hash and the public key that corresponds to the private key stored in Zyllion. During verification:
Use the signature (r, s) values returned from SecretSigner
tecdsa_signature
outputHash the message using SHA-256
Verify using any standard ECDSA verification library
Since SecretSigner returns standard ECDSA signatures, verification works just like it would for any other ECDSA signature.
Last updated