This commit is contained in:
Sergio Chouhy
2025-08-05 14:21:38 -03:00
parent 09046d3934
commit 56161e56d5
8 changed files with 17 additions and 145 deletions

View File

@@ -4,5 +4,4 @@ members = [
"encryption-demo",
"encryption-demo-methods",
"encryption-demo-methods/guest/chacha20",
"encryption-demo-methods/guest/xchacha20",
]

View File

@@ -12,5 +12,5 @@ risc0-zkvm = { version = "2.3.1", default-features = false }
risc0-build = { version = "2.3.1", default-features = false }
[package.metadata.risc0]
methods = ["guest/chacha20", "guest/xchacha20"]
methods = ["guest/chacha20"]

View File

@@ -4,14 +4,13 @@ version = "0.1.0"
edition = "2021"
publish = false
# Ensure staticlib for RISC-V
crate-type = ["staticlib"]
[dependencies]
# no_std stream cipher
chacha20 = { version = "0.9", default-features = false }
cipher = { version = "0.4", default-features = false }
risc0-zkvm = { version = "2.2.0", default-features = false, features = ['std'] }
risc0-zkvm-guest = "2.3.1"
[features]
default = ["alloc"] # pull in alloc inside guest

View File

@@ -1,10 +1,6 @@
#![no_std]
#![no_main]
use chacha20::cipher::{KeyIvInit, StreamCipher};
use chacha20::ChaCha20;
use risc0_zkvm::guest::env;
risc0_zkvm_guest::entry!(main);
pub fn main() {
// Read 32-byte key
@@ -14,14 +10,13 @@ pub fn main() {
// Read plaintext length
let len: u32 = env::read();
// Read plaintext bytes
let mut plaintext = vec![0u8; len as usize];
env::read_slice(&mut plaintext).unwrap();
let mut plaintext: Vec<_> = env::read();
// Encrypt in-place
let mut cipher = ChaCha20::new(&key.into(), &nonce.into());
cipher.apply_keystream(&mut plaintext);
// Commit ciphertext
env::commit_slice(&plaintext);
env::commit(&plaintext);
}

View File

@@ -1,19 +0,0 @@
[package]
name = "xchacha20"
version = "0.1.0"
edition = "2021"
publish = false
# Ensure staticlib for RISC-V
crate-type = ["staticlib"]
[dependencies]
# no_std stream cipher
xchacha20 = { version = "0.9", default-features = false }
cipher = { version = "0.4", default-features = false }
risc0-zkvm-guest = "2.3.1"
[features]
default = ["alloc"] # pull in alloc inside guest
alloc = []

View File

@@ -1,21 +0,0 @@
#![no_std]
#![no_main]
use chacha20::cipher::{KeyIvInit, StreamCipher};
use chacha20::XChaCha20;
use risc0_zkvm::guest::env;
risc0_zkvm_guest::entry!(main);
pub fn main() {
let key: [u8; 32] = env::read();
let nonce: [u8; 24] = env::read();
let len: u32 = env::read();
let mut plaintext = vec![0u8; len as usize];
env::read_slice(&mut plaintext).unwrap();
let mut cipher = XChaCha20::new(&key.into(), &nonce.into());
cipher.apply_keystream(&mut plaintext);
env::commit_slice(&plaintext);
}

View File

@@ -4,7 +4,7 @@ use risc0_zkvm::{
default_prover, ExecutorEnv, Receipt,
};
use encryption_demo_methods::{
CHACHA20_ELF, CHACHA20_ID, XCHACHA20_ELF, XCHACHA20_ID,
CHACHA20_ELF, CHACHA20_ID
};
/// Encrypt `plaintext` with ChaCha20 inside the zkVM.
@@ -13,102 +13,20 @@ pub fn encrypt_chacha20(
key: &[u8; 32],
nonce: &[u8; 12],
plaintext: &[u8],
) -> anyhow::Result<(Vec<u8>, Receipt)> {
) {
let env = ExecutorEnv::builder()
.write(key)?
.write(nonce)?
.write(&(plaintext.len() as u32))?
.write_slice(plaintext)?
.build()?;
.write(key).unwrap()
.write(nonce).unwrap()
.write(&(plaintext.len() as u32)).unwrap()
.write(&plaintext).unwrap()
.build().unwrap();
let prover = default_prover();
let receipt = prover.prove(env, CHACHA20_ELF)?;
receipt.verify(CHACHA20_ID)?;
let ciphertext: Vec<u8> = 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<u8>, 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<u8> = receipt.journal.decode()?;
Ok((ciphertext, receipt))
let prove_info = prover.prove(env, CHACHA20_ELF).unwrap();
// receipt.verify(CHACHA20_ID)?;
//
// let ciphertext: Vec<u8> = 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);
}
}

View File

@@ -1 +1,2 @@
fn main() {}