<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ansh-Sonkusare</title>
    <description>The latest articles on DEV Community by Ansh-Sonkusare (@anshsonkusare).</description>
    <link>https://dev.to/anshsonkusare</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F763386%2F46b8ab2a-f362-44df-b9e1-c7514989f3ca.png</url>
      <title>DEV Community: Ansh-Sonkusare</title>
      <link>https://dev.to/anshsonkusare</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/anshsonkusare"/>
    <language>en</language>
    <item>
      <title>Secrets In, Proofs Out: How Witnesses Power Midnight Privacy</title>
      <dc:creator>Ansh-Sonkusare</dc:creator>
      <pubDate>Tue, 08 Sep 2026 08:50:09 +0000</pubDate>
      <link>https://dev.to/anshsonkusare/secrets-in-proofs-out-how-witnesses-power-midnight-privacy-10cn</link>
      <guid>https://dev.to/anshsonkusare/secrets-in-proofs-out-how-witnesses-power-midnight-privacy-10cn</guid>
      <description>&lt;p&gt;Imagine you open a private voting app. You cast a vote, your vote is counted, and the&lt;br&gt;
result is public for everyone to see — but &lt;strong&gt;nobody, not even the machine counting the&lt;br&gt;
votes, ever sees &lt;em&gt;which&lt;/em&gt; vote was yours&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That sounds impossible. And on most blockchains it kind of is.&lt;/p&gt;

&lt;p&gt;Midnight does it with something called a &lt;strong&gt;witness&lt;/strong&gt;. This post explains what a witness&lt;br&gt;
is, how it works, and why it matters — using plain language and one running example you&lt;br&gt;
can follow from start to finish. No cryptography degree needed.&lt;/p&gt;
&lt;h2&gt;
  
  
  The core idea: use a secret without giving it away
&lt;/h2&gt;

&lt;p&gt;Every blockchain is basically a shared public notebook. When you write to it, everyone in&lt;br&gt;
the world can read what you wrote. That's great for honesty — but terrible if you want to&lt;br&gt;
keep something private.&lt;/p&gt;

&lt;p&gt;Here's the trick Midnight pulls off: you can let the network &lt;em&gt;check&lt;/em&gt; something about your&lt;br&gt;
private data without ever &lt;em&gt;seeing&lt;/em&gt; the data itself.&lt;/p&gt;

&lt;p&gt;Think of it like a lie-detector test for math. You whisper your answer to me. I don't&lt;br&gt;
tell anyone what you said. Instead, I stand up and say: &lt;em&gt;"I can prove this person's&lt;br&gt;
answer was valid, without showing you the answer."&lt;/em&gt; If everyone trusts me, they accept&lt;br&gt;
your answer without ever learning it.&lt;/p&gt;

&lt;p&gt;In Midnight, your private data never leaves your phone. Only a &lt;strong&gt;proof&lt;/strong&gt; that the data is&lt;br&gt;
correct travels to the network. And the person who "whispers" your secret into the proof&lt;br&gt;
is called a &lt;strong&gt;witness&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  What, exactly, is a witness?
&lt;/h2&gt;

&lt;p&gt;A witness is a helper that runs &lt;em&gt;on your own device&lt;/em&gt;, not on the blockchain.&lt;/p&gt;

&lt;p&gt;Here's the analogy that clicks for most people:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Your private data is a key hidden in your pocket. A witness is your hand — it reaches&lt;br&gt;
into your pocket, grabs the key, uses it to open a lock, and pulls out a &lt;em&gt;receipt&lt;/em&gt; that&lt;br&gt;
proves the door opened. Everyone sees the receipt. Nobody sees the key.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In Midnight's programming language (called Compact), a witness is declared inside the&lt;br&gt;
smart contract but its actual logic lives in your app's code, running locally.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// This tells the contract: "hey, there's a helper that can grab the secret key"
witness localSecretKey(): Bytes&amp;lt;32&amp;gt;;
witness localVote(): Uint&amp;lt;8&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice: there's &lt;strong&gt;no implementation here&lt;/strong&gt;. Compact just declares &lt;em&gt;that&lt;/em&gt; a witness exists.&lt;br&gt;
Your app provides the actual "reach into the pocket and grab the key" part later. The&lt;br&gt;
secret itself is never compiled into the on-chain contract, so it can never leak.&lt;/p&gt;
&lt;h2&gt;
  
  
  The "private oracle" — a fancy name for a simple idea
&lt;/h2&gt;

&lt;p&gt;Midnight borrows a term: the &lt;strong&gt;private oracle&lt;/strong&gt;. It just means two things working together:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Private state&lt;/strong&gt; — a small file on your device holding your secrets (your key, your
vote, your balance).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Witness functions&lt;/strong&gt; — the helpers that read from that file.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it. When a circuit needs your secret, it calls a witness, the witness reads your&lt;br&gt;
local file, and hands the value into the math that builds a proof. The secret stays on&lt;br&gt;
your device the whole time.&lt;/p&gt;
&lt;h2&gt;
  
  
  A running example: your private score
&lt;/h2&gt;

&lt;p&gt;Let's make this real. Say you're building an app where players have a &lt;strong&gt;score&lt;/strong&gt;, and you&lt;br&gt;
want to prove your score is legit on the blockchain — without ever revealing what the&lt;br&gt;
score is, or who you are.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1: Tell Compact about your secrets
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;witness localSecretKey(): Bytes&amp;lt;32&amp;gt;;   // your private key
witness localScore(): Uint&amp;lt;64&amp;gt;;        // your score
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Step 2: Turn the score into a "locked box"
&lt;/h3&gt;

&lt;p&gt;You don't put the raw score on-chain. You put a &lt;strong&gt;hash&lt;/strong&gt; of it — a scrambled, one-way&lt;br&gt;
fingerprint. It's like sealing your score inside a box and writing only the seal's&lt;br&gt;
serial number on the wall. Anyone can see the serial number. Nobody can open the box.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;circuit commitment(sk: Bytes&amp;lt;32&amp;gt;, score: Uint&amp;lt;64&amp;gt;): Bytes&amp;lt;32&amp;gt; {
  return persistentHash(...);   // the "seal"
}

export circuit commitScore(): [] {
  const _sk = localSecretKey();        // the hand reaches into the pocket
  const score = localScore();          // grabs the secret score
  scoreCommitment = disclose(commitment(_sk, score));  // only the seal goes on-chain
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Write the witnesses in your app's code
&lt;/h3&gt;

&lt;p&gt;Now the part you actually write as a developer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;witnesses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// "Reach into the pocket, grab the secret key"&lt;/span&gt;
  &lt;span class="na"&gt;localSecretKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;privateState&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;privateState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;privateState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;secretKey&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;

  &lt;span class="c1"&gt;// "Reach into the pocket, grab the score"&lt;/span&gt;
  &lt;span class="na"&gt;localScore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;privateState&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;privateState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;privateState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each witness returns two things: the (maybe-updated) private state, and the value the&lt;br&gt;
circuit asked for. The score and key are read straight from the user's own device.&lt;/p&gt;
&lt;h3&gt;
  
  
  What ends up on the blockchain?
&lt;/h3&gt;

&lt;p&gt;Just a &lt;strong&gt;hash&lt;/strong&gt; — a meaningless-looking string of characters. Nobody can reverse it to&lt;br&gt;
find your score. Your private data never left your device. Yet the network can still&lt;br&gt;
verify your commitment is legitimate whenever you reveal it later, by re-checking the&lt;br&gt;
hash.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why &lt;code&gt;disclose()&lt;/code&gt; is the guardrail
&lt;/h2&gt;

&lt;p&gt;Midnight is paranoid about privacy on purpose. The language refuses to let you accidentally&lt;br&gt;
publish private data.&lt;/p&gt;

&lt;p&gt;By default, anything that came from a witness is treated as &lt;strong&gt;private&lt;/strong&gt;. If you try to&lt;br&gt;
write it to the public ledger without saying so, the compiler stops you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// This won't even compile. It would leak private data.
scoreCommitment = commitment(sk, score);

// This compiles: you're explicitly saying "yes, publish this on purpose."
scoreCommitment = disclose(commitment(sk, score));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The word &lt;code&gt;disclose()&lt;/code&gt; is essentially billingual to the compiler: &lt;em&gt;"I know this came from&lt;br&gt;
private data. I'm doing it on purpose. Let me through."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Even clever attempts to hide it get caught. For example, if you take a secret, run it&lt;br&gt;
through some math, compare it to a public value, and then try to publish the &lt;em&gt;result&lt;/em&gt; of&lt;br&gt;
that comparison — the compiler traces the whole path back to the secret and refuses.&lt;/p&gt;

&lt;p&gt;Here's how to read one rule of thumb:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If a value is &lt;strong&gt;private&lt;/strong&gt;, treat it like it's radioactive.&lt;/li&gt;
&lt;li&gt;The only way to let it touch public things is to wrap it in &lt;code&gt;disclose()&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  One big warning: don't trust the witness
&lt;/h2&gt;

&lt;p&gt;Here's the part that surprises people: &lt;strong&gt;the witness is not magic, and it is not trustworthy&lt;br&gt;
by itself.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Remember: the witness runs on &lt;em&gt;your&lt;/em&gt; device, in &lt;em&gt;your&lt;/em&gt; app. If you're the one writing the&lt;br&gt;
app, you write the honest witness. But the blockchain can't assume that. Anyone could ship&lt;br&gt;
a witness that returns fake values.&lt;/p&gt;

&lt;p&gt;That's why the smart contract must &lt;strong&gt;double-check&lt;/strong&gt; whatever the witness hands over —&lt;br&gt;
against data that's already on the chain. In our example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, we put the commitment (the "seal") on the chain.&lt;/li&gt;
&lt;li&gt;Later, when you reveal, the contract recomputes the seal and compares it to what's on
the chain.&lt;/li&gt;
&lt;li&gt;If a witness tried to lie, the seals wouldn't match, and the contract rejects it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A witness can tell you anything. The math on-chain is what actually holds it accountable.&lt;/p&gt;

&lt;h2&gt;
  
  
  When should you use a witness?
&lt;/h2&gt;

&lt;p&gt;Use a witness when you need to touch private data or do hard off-device math:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read a secret key, vote, or balance that must never be public&lt;/li&gt;
&lt;li&gt;Do division or other math the blockchain can't do cheaply, then prove the result&lt;/li&gt;
&lt;li&gt;Update private state based on what happened in a circuit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don't use a witness as a shortcut around good design — anything important it returns must&lt;br&gt;
eventually be checked against on-chain truth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tell me the whole thing again, simply
&lt;/h2&gt;

&lt;p&gt;Here's the entire idea in one paragraph:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A witness is a helper that runs on your own device. When your smart contract needs a&lt;br&gt;
secret, it calls the witness, which pulls the secret from your private local file and&lt;br&gt;
feeds it into a zero-knowledge proof. Only the proof goes to the blockchain — never the&lt;br&gt;
secret itself. And &lt;code&gt;disclose()&lt;/code&gt; is your explicit, compiler-enforced "yes I meant to share&lt;br&gt;
this" button for the rare times something does become public.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A quick glossary in plain words
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Witness&lt;/strong&gt; — a helper on your device that supplies private data to a proof&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private state&lt;/strong&gt; — the secrets living in a local file on your device&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private oracle&lt;/strong&gt; — private state + the witnesses that read it, working together&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hash / commitment&lt;/strong&gt; — a one-way "seal" of your data; public to see, impossible to open&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;disclose()&lt;/strong&gt; — the explicit "share this" tag the compiler requires before private data
can touch the public ledger&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Learn more
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.midnight.network/concepts/how-midnight-works/compact-privacy-first-language" rel="noopener noreferrer"&gt;Compact as a privacy-first language (official docs)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.midnight.network/compact/reference/explicit-disclosure" rel="noopener noreferrer"&gt;Explicit disclosure (official docs)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.midnight.network/blog/compact-2" rel="noopener noreferrer"&gt;Midnight Dev Diaries — Circuit and Witness Calls&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
  </channel>
</rss>
