# Generating Keys and Signatures

The price oracle must securely store an `HMAC_SECRET` key (used to generate threshold keys), and `SIGN_SECRET` key (used to sign responses):

```javascript
// Used to generate a unique secret key for each price quote:
HMAC_SECRET = 32 (or more) randomly generated bytes.

// Used to provide a signature with each price quote:
SIGN_SECRET = 32 randomly generated bytes (on the secp256k1 curve).

// Compressed public key of the signing secret key.
ORACLE_PK   = get_ecdsa_compressed_pubkey(SIGN_SECRET)// Some code
```

When the oracle receives a request, the `thold_key` and `thold_hash` can be generated using the following formula:

```javascript
DOMAIN_LABEL  = utf8_to_bytes("bitcoin/usd_price_quote")
QUOTE_PRICE   = uint32_to_bytes(quote_price, size=4)
QUOTE_STAMP   = uint32_to_bytes(quote_stamp, size=4)
THOLD_PRICE   = uint32_to_bytes(thold_price, size=4)
THOLD_KEY     = hmac256(HMAC_SECRET, DOMAIN_LABEL, ORACLE_PK, QUOTE_PRICE, QUOTE_STAMP, THOLD_PRICE)
THOLD_HASH    = ripemd160(sha256(THOLD_KEY))
```

When providing a response, the contents of the price quote must be hashed and signed using the following formula:

```javascript
PREIMAGE = json_to_utf8_bytes({
  expiry_price : number | null // Price of the first exchange record to cross threshold.
  expiry_stamp : number | null // Timestamp of the first exchange record to cross threshold. 
  is_expired   : boolean       // If the threshold has been crossed.
  oracle_pk    : string        // Public key belonging to the Price Oracle.
  quote_price  : number        // The exchange price of the quote.
  quote_stamp  : number        // The exchange timestamp of the quote.
  req_stamp    : number        // Timestamp of the latest exchange record.
  thold_hash   : string        // HASH160 hash of the threshold key.
  thold_key    : string | null // HMAC256 key controlling the stop-loss event.
  thold_price  : number        // Threshold price that was provided with the request.
})
REQUEST_ID  = sha256(PREIMAGE)
REQUEST_SIG = ecdsa_sign(SIGN_SECRET, PREIMAGE)
```

<br>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ducatprotocol.com/how-ducat-works/oracles/generating-keys-and-signatures.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
