# Stark signatures Payloads to stark signing are a result of a Pedersen hash. Depending on your implementation of the Pedersen hash, the result of this hash might be an integer, or encoded in 32-byte representation, according to [Deterministic Usage of the Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA)](https://www.rfc-editor.org/rfc/rfc6979#section-2.3.2). Fordefi supports these formats: - `hash_integer`: This is the integer representation, encoded as a hex string, starting with 0x and followed by an even number of hex-digits. - `hash_binary`: This is the 32-byte encoded format. Once the payload is signed, under the `details` field in the `Get Transaction` response, the `signature` object will hold the R- and S-values of the signature. ### Example This example demonstrates how to use the new stark vault for creating and signing stark signatures. ```python import requests import base64 import json import datetime import ecdsa import hashlib # https://github.com/starkware-libs/cairo-lang from starkware.crypto.signature.signature import verify, pedersen_hash # Obtain the hash of the transaction payload_int = pedersen_hash(0xdeadbeaf) # Build the signature request request_json = { "vault_id": vault_id, "note":" string", "signer_type": "api_signer", "type": "black_box_signature", "details": { "format": "hash_integer", "hash_integer": "0x{:064x}".format(payload_int), }, } # Alternatively, you can use the binary hash # this is useful if pedersen_hash implementation you are using returns bytes according to https://www.rfc-editor.org/rfc/rfc6979#section-2.3.2 payload_bytes = b"0" * 32 payload_encoded = base64.b64encode(payload_bytes).decode() request_json = { "vault_id": vault_id, "note":" string", "signer_type": "api_signer", "type": "black_box_signature", "details": { "format": "hash_binary", "hash_binary": payload_encoded, }, } request_body = json.dumps(request_json) private_key_file = "private.pem" timestamp = datetime.datetime.now().strftime("%s") payload = f"/api/v1/transactions|{timestamp}|{request_body}" with open(private_key_file, "r") as f: signing_key = ecdsa.SigningKey.from_pem(f.read()) signature = signing_key.sign(data=payload.encode(), hashfunc=hashlib.sha256, sigencode=ecdsa.util.sigencode_der) resp_tx = requests.post( f"https://{gateway_host}/api/v1/transactions", headers={ "Authorization": f"Bearer {access_token}", "x-signature": base64.b64encode(signature), "x-timestamp": timestamp.encode(), }, data=request_body, ).json() # Obtain the signature result transaction_id = resp_tx["id"] signed_transaction = requests.get( f"https://{gateway_host}/api/v1/transactions/{transaction_id}", headers={ "Authorization": f"Bearer {access_token}", } ).json() r = int(signed_transaction["details"]["signature"]["r"], 16) s = int(signed_transaction["details"]["signature"]["s"], 16) # Obtain your vault's public key vault = requests.get( f"https://{gateway_host}/api/v1/vaults/{vault_id}", headers={ "Authorization": f"Bearer {access_token}", } ).json() stark_key = int(vault["details"]["stark_key"], 16) # Verify the signature assert verify(payload_int, r, s, stark_key) # You can also use the public key in the compressed format compressed_public_key = base64.b64decode(vault["public_key_compressed"]) # This is the relation between the compressed public key and the stark key assert int.from_bytes(compressed_public_key[1:], byteorder="big") == stark_key ``` ##