Skip to content

Java-Idl/c-schnorr-zkp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

C Schnorr Zero-Knowledge Proof (ZKP)

This folder contains a true interactive Schnorr sigma-protocol implementation in C.

  • Prover secret: x
  • Public key: y = g^x mod p
  • Commitment: t = g^r mod p
  • Challenge: c
  • Response: s = r + c*x (mod q)
  • Verification equation: g^s == t * y^c (mod p)

Unlike a simple hash/password check, this is an actual proof-of-knowledge challenge-response protocol.

Files

  • schnorr.h: public types and function declarations
  • schnorr.c: protocol and parameter generation implementation
  • main.c: interactive demo executable
  • tests.c: test runner with positive/negative protocol checks

Security model

  • Uses system CSPRNG (BCryptGenRandom on Windows, /dev/urandom on POSIX)
  • Generates safe-prime-style parameters at runtime (p = 2q + 1, with primality checks)
  • Uses multiple rounds to decrease false-accept probability for an impostor

Note: This is educational code using small (~31-bit) subgroup sizes for performance and readability in plain C without big-integer libraries.

Build

GCC / Clang (Linux/macOS)

gcc -O2 -std=c11 -Wall -Wextra -pedantic -o schnorr_demo main.c schnorr.c
gcc -O2 -std=c11 -Wall -Wextra -pedantic -o schnorr_tests tests.c schnorr.c

GCC (Windows MinGW)

gcc -O2 -std=c11 -Wall -Wextra -pedantic -o schnorr_demo main.c schnorr.c -lbcrypt
gcc -O2 -std=c11 -Wall -Wextra -pedantic -o schnorr_tests tests.c schnorr.c -lbcrypt

MSVC (Developer PowerShell)

cl /O2 /W4 main.c schnorr.c bcrypt.lib /Fe:schnorr_demo.exe
cl /O2 /W4 tests.c schnorr.c bcrypt.lib /Fe:schnorr_tests.exe

Run demo

./schnorr_demo

Optional rounds argument:

./schnorr_demo 20

Expected behavior:

  • Honest rounds print accepted=true
  • Built-in tamper check prints accepted=false

Run tests

./schnorr_tests

What the test cases mean

  • honest_rounds: Confirms normal prover/verifier flow succeeds across many rounds. If this fails, core protocol math is broken.

  • tamper_response: Mutates s by +1 mod q after a valid proof is created. Verifier must reject. If accepted, integrity is broken.

  • wrong_public_key: Verifies a valid proof against a different public key. Verifier must reject. If accepted, identity binding is broken.

  • random_forgery: Tries many forged tuples (t, c, s) not produced with witness x. Usually all reject; occasional accidental accepts are theoretically possible in finite groups.

How to create your own tests

Use tests.c as a template and add new functions with the pattern:

  1. Build or mutate a SchnorrProof
  2. Call schnorr_verify(...)
  3. Assert expected accept/reject outcome
  4. Print [PASS] or [FAIL]

Suggested custom tests:

  • Boundary challenge test: set challenge_c to 0 or q-1 and verify equation behavior.
  • Replay behavior: verify same proof multiple times against same public key (should consistently pass if unmodified).
  • Cross-parameter mismatch: generate proof under one (p,q,g) set and verify under another (must reject).
  • Stress run: increase honest rounds and forgery attempts for statistical confidence.

Interpreting failures

  • Failure in positive test (honest_rounds) indicates functional bug.
  • Failure in negative test (tamper_response, wrong_public_key) indicates security bug.
  • High acceptance rate in random_forgery indicates serious issue; tiny nonzero rates can occur by chance in small educational parameter sizes.

gcc -O2 -std=c11 -Wall -Wextra -pedantic -o schnorr_demo main.c schnorr.c -lbcrypt; gcc -O2 -std=c11 -Wall -Wextra -pedantic -o schnorr_tests tests.c schnorr.c -lbcrypt

About

interactive Schnorr sigma-protocol implementation in C

Topics

Resources

Stars

Watchers

Forks

Contributors

Languages