From 579bf0a624cd99db3c8927f68a904aa2105a9563 Mon Sep 17 00:00:00 2001 From: Moudy Date: Tue, 5 Aug 2025 13:31:57 +0200 Subject: [PATCH] encryption example with risc0 --- .DS_Store | Bin 0 -> 8196 bytes Cargo.toml | 6 + encryption-demo-methods/Cargo.toml | 15 +++ encryption-demo-methods/build.rs | 4 + .../guest/chacha20/Cargo.toml | 19 +++ .../guest/chacha20/src/main.rs | 27 +++++ .../guest/xchacha20/Cargo.toml | 19 +++ .../guest/xchacha20/src/main.rs | 21 ++++ encryption-demo-methods/src/lib.rs | 2 + encryption-demo/Cargo.toml | 16 +++ encryption-demo/encryption-demo/src/main.rs | 14 +++ encryption-demo/src/lib.rs | 114 ++++++++++++++++++ encryption-demo/src/main.rs | 1 + risc0-selective-privacy-poc/.DS_Store | Bin 0 -> 6148 bytes 14 files changed, 258 insertions(+) create mode 100644 .DS_Store create mode 100644 Cargo.toml create mode 100644 encryption-demo-methods/Cargo.toml create mode 100644 encryption-demo-methods/build.rs create mode 100644 encryption-demo-methods/guest/chacha20/Cargo.toml create mode 100644 encryption-demo-methods/guest/chacha20/src/main.rs create mode 100644 encryption-demo-methods/guest/xchacha20/Cargo.toml create mode 100644 encryption-demo-methods/guest/xchacha20/src/main.rs create mode 100644 encryption-demo-methods/src/lib.rs create mode 100644 encryption-demo/Cargo.toml create mode 100644 encryption-demo/encryption-demo/src/main.rs create mode 100644 encryption-demo/src/lib.rs create mode 100644 encryption-demo/src/main.rs create mode 100644 risc0-selective-privacy-poc/.DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..1472fea03afefdd29f856e433147c816ce7bcb5d GIT binary patch literal 8196 zcmeHMyKWOf6g@+1V<{k|O9agdAu5960*ObnL<`hWJ|GV}N)TRlWhdcLtthBb_yKx^ zM1w?07YZbxpoRib17E#ZG+vW@OnmH&_>S2&KB0v!=mg^T02y^BZjiW*&n&M z*xABbI~>X#K9oaN?u4QYI`c;+94fXpv_XNOKve;Kc5mPUHgOBv-ub=x{E76XS(2>x zvvu~hXV3rmbZK_~n(yx&=+C#ryMf~i9Ev9HU<3ECgQ16v=^MURVh{FKK3=rgVtks7 z&?iTD_;_sb2b}c~T`c(c=bjn-(kt=zUI}~=F~Xl5;p0Em_@_~h$2@s#pwHUHHd*cR zY96_X*u@%q@0-sVx{~XahsBx0XOi<`mUow}u7~6$?*X%Y{=IBcud6rTGa*{kXp345 zs7+6*0G#+f?w51>vR~daFNb7Y7bAJNJ#C6Sa&$Zfjg=2%;5-uh<*C(Q>$UWb)=Jgu z;WfY6dFvI>=c?#o%|k`|tC_d(OYEhr#BOm#l{w_R>tZ|}oUXxnfZIsPBOm|9F1;Q1 zOCHH1!9(PbJnCXR9(FfxLFc&3`3#ZzdYpVw@^F61BYHE&ql_8dk-8X<2VN5-F#dkMtY^`Jg~h;9vz*BUw%s8RO2@m1up|j#yV&b anyhow::Result<()> { + let msg = b"zk-encrypted hello world!"; + let mut rng = rand::thread_rng(); + let key: [u8; 32] = rng.gen(); + let nonce: [u8; 12] = rng.gen(); + + let (ciphertext, _proof) = encrypt_chacha20(&key, &nonce, msg)?; + println!("ciphertext = {}", hex::encode(ciphertext)); + println!("proof OK"); + Ok(()) +} diff --git a/encryption-demo/src/lib.rs b/encryption-demo/src/lib.rs new file mode 100644 index 0000000..feaab80 --- /dev/null +++ b/encryption-demo/src/lib.rs @@ -0,0 +1,114 @@ +//! Host-side helpers: prove encryption inside RISC Zero and verify receipts. + +use risc0_zkvm::{ + default_prover, ExecutorEnv, Receipt, +}; +use encryption_demo_methods::{ + CHACHA20_ELF, CHACHA20_ID, XCHACHA20_ELF, XCHACHA20_ID, +}; + +/// Encrypt `plaintext` with ChaCha20 inside the zkVM. +/// Returns `(ciphertext, receipt)`. +pub fn encrypt_chacha20( + key: &[u8; 32], + nonce: &[u8; 12], + plaintext: &[u8], +) -> anyhow::Result<(Vec, Receipt)> { + let env = ExecutorEnv::builder() + .write(key)? + .write(nonce)? + .write(&(plaintext.len() as u32))? + .write_slice(plaintext)? + .build()?; + + let prover = default_prover(); + let receipt = prover.prove(env, CHACHA20_ELF)?; + receipt.verify(CHACHA20_ID)?; + + let ciphertext: Vec = receipt.journal.decode()?; + Ok((ciphertext, receipt)) +} + +/// Same API for XChaCha20 (24-byte nonce) +pub fn encrypt_xchacha20( + key: &[u8; 32], + nonce: &[u8; 24], + plaintext: &[u8], +) -> anyhow::Result<(Vec, Receipt)> { + let env = ExecutorEnv::builder() + .write(key)? + .write(nonce)? + .write(&(plaintext.len() as u32))? + .write_slice(plaintext)? + .build()?; + + let prover = default_prover(); + let receipt = prover.prove(env, XCHACHA20_ELF)?; + receipt.verify(XCHACHA20_ID)?; + + let ciphertext: Vec = receipt.journal.decode()?; + Ok((ciphertext, receipt)) +} + + +// Test for chacha20 +#[cfg(test)] +mod tests { + use super::*; + use chacha20::cipher::{KeyIvInit, StreamCipher}; + use chacha20::ChaCha20; + + // RFC 8439 test vector + const KEY: [u8; 32] = [ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + ]; + const NONCE: [u8; 12] = [0; 12]; + const PLAINTEXT: [u8; 16] = *b"example message!"; + + #[test] + fn chacha20_vector_matches() { + let (ciphertext, _) = encrypt_chacha20(&KEY, &NONCE, &PLAINTEXT).unwrap(); + + // host decryption + let mut buf = ciphertext.clone(); + let mut cipher = ChaCha20::new(&KEY.into(), &NONCE.into()); + cipher.apply_keystream(&mut buf); + + assert_eq!(&buf, &PLAINTEXT); + } +} + + +// Tests for Xchacha20 +#[cfg(test)] +mod tests { + use super::*; + use xchacha20::cipher::{KeyIvInit, StreamCipher}; + use xchacha20::xChaCha20; + + // RFC 8439 test vector + const KEY: [u8; 32] = [ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + ]; + const NONCE: [u8; 12] = [0; 12]; + const PLAINTEXT: [u8; 16] = *b"example message!"; + + #[test] + fn xchacha20_vector_matches() { + let (ciphertext, _) = encrypt_xchacha20(&KEY, &NONCE, &PLAINTEXT).unwrap(); + + // host decryption + let mut buf = ciphertext.clone(); + let mut cipher = xChaCha20::new(&KEY.into(), &NONCE.into()); + cipher.apply_keystream(&mut buf); + + assert_eq!(&buf, &PLAINTEXT); + } +} + diff --git a/encryption-demo/src/main.rs b/encryption-demo/src/main.rs new file mode 100644 index 0000000..1a4baf5 --- /dev/null +++ b/encryption-demo/src/main.rs @@ -0,0 +1 @@ + diff --git a/risc0-selective-privacy-poc/.DS_Store b/risc0-selective-privacy-poc/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..a84a518e783f0aeeada57137811323ced2d215d1 GIT binary patch literal 6148 zcmeHKy-ou$47Q;{Cw1utV>afFv`aW$7bc{>0FukSbe{#DyFvt>Jjy?Xon`nWpZULVHHcQNo?jtVjBr(d4N^)13& zoB?OR8E^)ifuk^hJ6ojcD|+t?I0MeWjsZCz0-9hnOp5vFK$lAZpgg0qK$luVa)Mzr zOp5S8SW|(T%2r~qro$dAE*d69O((YEgKg!X;)V0-m_Ouj;;87oGvEw#893G9K<@tu zewkvC-%at6GvEyTGX}WVOq&`XWq0er=gD0g(C*MgBrb^pf!=upU?AtnMRuw`h>o~u Wm=t9evFCK4KLj!%-Z=wDVBi}T2rWne literal 0 HcmV?d00001