mirror of
https://github.com/logos-blockchain/lssa-zkvm-testing.git
synced 2026-01-03 22:03:10 +00:00
Merge e2b8bf42a585c6669be262e3624f4b2b3060037a into 48370d4e22dd3864570f72bf74b5c4a0becfe5fc
This commit is contained in:
commit
1034c5074d
BIN
chacha20-demo/.DS_Store
vendored
Normal file
BIN
chacha20-demo/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
chacha20-demo/methods/.DS_Store
vendored
Normal file
BIN
chacha20-demo/methods/.DS_Store
vendored
Normal file
Binary file not shown.
4
shake256-33bytes-demo/.gitignore
vendored
Normal file
4
shake256-33bytes-demo/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
/target
|
||||
**/target
|
||||
/target 2
|
||||
**/target 2
|
||||
32
shake256-33bytes-demo/Cargo.toml
Normal file
32
shake256-33bytes-demo/Cargo.toml
Normal file
@ -0,0 +1,32 @@
|
||||
[package]
|
||||
name = "shake256-33bytes-demo"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
build = "build.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "shake256-33bytes-demo"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
risc0-zkvm = { version = "2.3.1", features = ["std", "prove"] }
|
||||
anyhow = "1.0"
|
||||
hex = "0.4"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
sha2 = "0.10"
|
||||
hkdf = "0.12"
|
||||
sha3 = "0.10"
|
||||
serde-big-array = "0.5"
|
||||
tiny-keccak = { version = "2", default-features = false, features = ["shake"] } # ADD
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.8"
|
||||
cipher = { version = "0.4", features = ["std"] }
|
||||
serde = { version = "1", default-features = false, features = ["derive", "alloc"] }
|
||||
|
||||
[package.metadata.risc0]
|
||||
methods = ["methods/guest"]
|
||||
# methods = {path = "methods"}
|
||||
|
||||
[build-dependencies]
|
||||
risc0-build = "2.3.1"
|
||||
3
shake256-33bytes-demo/build.rs
Normal file
3
shake256-33bytes-demo/build.rs
Normal file
@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
risc0_build::embed_methods();
|
||||
}
|
||||
11
shake256-33bytes-demo/methods/Cargo.toml
Normal file
11
shake256-33bytes-demo/methods/Cargo.toml
Normal file
@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "methods"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[build-dependencies]
|
||||
risc0-build = { version = "2.3.1" }
|
||||
|
||||
[package.metadata.risc0]
|
||||
methods = ["guest"]
|
||||
|
||||
3
shake256-33bytes-demo/methods/build.rs
Normal file
3
shake256-33bytes-demo/methods/build.rs
Normal file
@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
risc0_build::embed_methods();
|
||||
}
|
||||
14
shake256-33bytes-demo/methods/guest/Cargo.toml
Normal file
14
shake256-33bytes-demo/methods/guest/Cargo.toml
Normal file
@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "guest"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[workspace]
|
||||
|
||||
[dependencies]
|
||||
risc0-zkvm = { version = "2.3.1", default-features = false}
|
||||
serde = { version = "1", default-features = false, features = ["derive", "alloc"] }
|
||||
sha2 = { version = "0.10", default-features = false }
|
||||
hkdf = { version = "0.12", default-features = false }
|
||||
sha3 = { version = "0.10", default-features = false }
|
||||
tiny-keccak = { version = "2", default-features = false, features = ["shake"] } # ADD
|
||||
132
shake256-33bytes-demo/methods/guest/src/main.rs
Normal file
132
shake256-33bytes-demo/methods/guest/src/main.rs
Normal file
@ -0,0 +1,132 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use risc0_zkvm::guest::env;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
// ---------- module 1 ----------
|
||||
mod ser_bytes33 {
|
||||
use core::fmt;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use serde::de::{self, SeqAccess, Visitor};
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct Bytes33(pub [u8; 33]);
|
||||
|
||||
impl Serialize for Bytes33 {
|
||||
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
|
||||
s.serialize_bytes(&self.0)
|
||||
}
|
||||
}
|
||||
impl<'de> Deserialize<'de> for Bytes33 {
|
||||
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
|
||||
struct V;
|
||||
impl<'de> Visitor<'de> for V {
|
||||
type Value = Bytes33;
|
||||
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "exactly 33 bytes")
|
||||
}
|
||||
fn visit_bytes<E: de::Error>(self, v: &[u8]) -> Result<Self::Value, E> {
|
||||
if v.len() != 33 { return Err(E::invalid_length(v.len(), &"33 bytes")); }
|
||||
let mut a = [0u8; 33];
|
||||
a.copy_from_slice(v);
|
||||
Ok(Bytes33(a))
|
||||
}
|
||||
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
|
||||
let mut a = [0u8; 33];
|
||||
for i in 0..33 {
|
||||
a[i] = seq.next_element()?
|
||||
.ok_or_else(|| de::Error::invalid_length(i, &"33 bytes"))?;
|
||||
}
|
||||
Ok(Bytes33(a))
|
||||
}
|
||||
}
|
||||
d.deserialize_bytes(V)
|
||||
}
|
||||
}
|
||||
impl AsRef<[u8; 33]> for Bytes33 { fn as_ref(&self) -> &[u8; 33] { &self.0 } }
|
||||
impl AsRef<[u8]> for Bytes33 { fn as_ref(&self) -> &[u8] { &self.0 } }
|
||||
}
|
||||
use ser_bytes33::Bytes33; // bring into crate scope
|
||||
// ---------- end module 1 ----------
|
||||
|
||||
// ---------- module 2 ----------
|
||||
mod crypto {
|
||||
#![allow(clippy::needless_borrows_for_generic_args)]
|
||||
|
||||
extern crate alloc;
|
||||
use alloc::vec;
|
||||
use alloc::vec::Vec;
|
||||
use sha2::{Digest, Sha256};
|
||||
use tiny_keccak::{Hasher, Shake};
|
||||
|
||||
pub fn nssa_kdf(
|
||||
ss_bytes: [u8; 32],
|
||||
epk: &[u8; 33],
|
||||
ipk: &[u8; 33],
|
||||
commitment: &[u8; 32],
|
||||
out_index: u32,
|
||||
) -> [u8; 32] {
|
||||
let mut hasher = Sha256::new();
|
||||
|
||||
hasher.update(b"NSSA/v0.1/KDF-SHA256");
|
||||
hasher.update(&ss_bytes);
|
||||
hasher.update(&epk[..]);
|
||||
hasher.update(&ipk[..]);
|
||||
hasher.update(&commitment[..]);
|
||||
hasher.update(&out_index.to_le_bytes());
|
||||
|
||||
hasher.finalize().into()
|
||||
}
|
||||
|
||||
pub fn enc_xor_shake256(key: &[u8; 32], info: &[u8], pt: &[u8]) -> Vec<u8> {
|
||||
let mut sh = Shake::v256();
|
||||
sh.update(b"NSSA/v0.1/shake-ks");
|
||||
sh.update(&key[..]);
|
||||
sh.update(info);
|
||||
|
||||
let mut ks = vec![0u8; pt.len()];
|
||||
sh.finalize(&mut ks);
|
||||
|
||||
let mut ct = vec![0u8; pt.len()];
|
||||
for (i, &b) in pt.iter().enumerate() {
|
||||
ct[i] = b ^ ks[i];
|
||||
}
|
||||
ct
|
||||
}
|
||||
}
|
||||
use crypto::{enc_xor_shake256, nssa_kdf};
|
||||
// ---------- end module 2 ----------
|
||||
|
||||
// ---------- plain types at crate root ----------
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct EncInput {
|
||||
pub ss_bytes: [u8; 32],
|
||||
pub epk_bytes: Bytes33,
|
||||
pub ipk_bytes: Bytes33,
|
||||
pub commitment: [u8; 32],
|
||||
pub out_index: u32,
|
||||
}
|
||||
// ---------- end types ----------
|
||||
|
||||
// ---------- entrypoint at crate root ----------
|
||||
risc0_zkvm::guest::entry!(guest_main);
|
||||
|
||||
pub fn guest_main() {
|
||||
let EncInput { ss_bytes, epk_bytes, ipk_bytes, commitment, out_index } = env::read();
|
||||
|
||||
let mut info: Vec<u8> = Vec::new();
|
||||
info.extend_from_slice(epk_bytes.as_ref());
|
||||
info.extend_from_slice(ipk_bytes.as_ref());
|
||||
info.extend_from_slice(&commitment);
|
||||
|
||||
let k_enc = nssa_kdf(ss_bytes, epk_bytes.as_ref(), ipk_bytes.as_ref(), &commitment, out_index);
|
||||
|
||||
let pt: &[u8] = b"hello";
|
||||
let ct = enc_xor_shake256(&k_enc, &info, pt);
|
||||
|
||||
env::commit_slice(&ct);
|
||||
}
|
||||
// ---------- end entry ----------
|
||||
1
shake256-33bytes-demo/methods/src/lib.rs
Normal file
1
shake256-33bytes-demo/methods/src/lib.rs
Normal file
@ -0,0 +1 @@
|
||||
include!(concat!(env!("OUT_DIR"), "/methods.rs"));
|
||||
115
shake256-33bytes-demo/src/lib.rs
Normal file
115
shake256-33bytes-demo/src/lib.rs
Normal file
@ -0,0 +1,115 @@
|
||||
pub mod methods {
|
||||
include!(concat!(env!("OUT_DIR"), "/methods.rs"));
|
||||
}
|
||||
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
// ---------- 33-byte wrapper (public) ----------
|
||||
pub mod ser_bytes33 { // (public so main.rs can use it)
|
||||
use core::fmt;
|
||||
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct Bytes33(pub [u8; 33]);
|
||||
|
||||
impl Serialize for Bytes33 {
|
||||
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
|
||||
s.serialize_bytes(&self.0)
|
||||
}
|
||||
}
|
||||
impl<'de> Deserialize<'de> for Bytes33 {
|
||||
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
|
||||
struct V;
|
||||
impl<'de> de::Visitor<'de> for V {
|
||||
type Value = Bytes33;
|
||||
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "exactly 33 bytes")
|
||||
}
|
||||
fn visit_bytes<E: de::Error>(self, v: &[u8]) -> Result<Self::Value, E> {
|
||||
if v.len() != 33 { return Err(E::invalid_length(v.len(), &"33 bytes")); }
|
||||
let mut a = [0u8; 33];
|
||||
a.copy_from_slice(v);
|
||||
Ok(Bytes33(a))
|
||||
}
|
||||
}
|
||||
d.deserialize_bytes(V)
|
||||
}
|
||||
}
|
||||
impl AsRef<[u8; 33]> for Bytes33 { fn as_ref(&self) -> &[u8; 33] { &self.0 } }
|
||||
impl AsRef<[u8]> for Bytes33 { fn as_ref(&self) -> &[u8] { &self.0 } }
|
||||
|
||||
// this is an optional QoL: it allows `epk_bytes.into()` from a plain array
|
||||
impl From<[u8; 33]> for Bytes33 {
|
||||
fn from(a: [u8; 33]) -> Self { Bytes33(a) }
|
||||
}
|
||||
}
|
||||
pub use ser_bytes33::Bytes33; // re-export
|
||||
// --------------------------------------------------
|
||||
|
||||
// ---------- crypto (public) ----------
|
||||
pub mod crypto { // makes the module public
|
||||
use sha2::{Digest, Sha256};
|
||||
use tiny_keccak::{Hasher, Shake};
|
||||
|
||||
pub fn nssa_kdf( // keeps public
|
||||
ss_bytes: [u8; 32],
|
||||
epk: &[u8; 33],
|
||||
ipk: &[u8; 33],
|
||||
commitment: &[u8; 32],
|
||||
out_index: u32,
|
||||
) -> [u8; 32] {
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(b"NSSA/v0.1/KDF-SHA256");
|
||||
hasher.update(&ss_bytes);
|
||||
hasher.update(&epk[..]);
|
||||
hasher.update(&ipk[..]);
|
||||
hasher.update(&commitment[..]);
|
||||
hasher.update(&out_index.to_le_bytes());
|
||||
hasher.finalize().into()
|
||||
}
|
||||
|
||||
pub fn enc_xor_shake256(key: &[u8; 32], info: &[u8], pt: &[u8]) -> Vec<u8> {
|
||||
let mut sh = Shake::v256();
|
||||
sh.update(b"NSSA/v0.1/shake-ks");
|
||||
sh.update(&key[..]);
|
||||
sh.update(info);
|
||||
|
||||
let mut ks = vec![0u8; pt.len()];
|
||||
sh.finalize(&mut ks);
|
||||
|
||||
let mut ct = vec![0u8; pt.len()];
|
||||
for (i, &b) in pt.iter().enumerate() {
|
||||
ct[i] = b ^ ks[i];
|
||||
}
|
||||
ct
|
||||
}
|
||||
}
|
||||
|
||||
// Re-export so callers can `use shake256_demo::{enc_xor_shake256, nssa_kdf};`
|
||||
pub use crypto::{enc_xor_shake256, nssa_kdf};
|
||||
// ------------------------------------------------------------
|
||||
|
||||
// ---------- types ----------
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct EncInput {
|
||||
pub ss_bytes: [u8; 32],
|
||||
pub epk_bytes: Bytes33,
|
||||
pub ipk_bytes: Bytes33,
|
||||
pub commitment: [u8; 32],
|
||||
pub out_index: u32,
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
pub fn build_info(epk: &Bytes33, ipk: &Bytes33) -> Vec<u8> {
|
||||
let mut info = Vec::with_capacity(66);
|
||||
info.extend_from_slice(epk.as_ref());
|
||||
info.extend_from_slice(ipk.as_ref());
|
||||
info
|
||||
}
|
||||
|
||||
pub fn example_use(input: &EncInput) -> ([u8; 32], Vec<u8>) {
|
||||
let info = build_info(&input.epk_bytes, &input.ipk_bytes);
|
||||
let k: [u8; 32] = [0u8; 32];
|
||||
(k, info)
|
||||
}
|
||||
75
shake256-33bytes-demo/src/main.rs
Normal file
75
shake256-33bytes-demo/src/main.rs
Normal file
@ -0,0 +1,75 @@
|
||||
use hex::ToHex;
|
||||
use risc0_zkvm::{default_prover, ExecutorEnv};
|
||||
|
||||
use shake256_33bytes_demo::{EncInput, enc_xor_shake256, nssa_kdf}; // now works via re-exports
|
||||
use shake256_33bytes_demo::ser_bytes33::Bytes33; // for constructing wrapper
|
||||
use shake256_33bytes_demo::methods::GUEST_ELF; // generated guest image
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
|
||||
let ss_bytes: [u8; 32] = [
|
||||
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
|
||||
0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
|
||||
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
|
||||
0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
|
||||
];
|
||||
|
||||
let commitment: [u8; 32] = [
|
||||
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
|
||||
0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
|
||||
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
|
||||
0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
|
||||
];
|
||||
|
||||
let epk_raw: [u8; 33] = [
|
||||
0x02,
|
||||
0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
|
||||
0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,
|
||||
0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,
|
||||
0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,
|
||||
];
|
||||
let ipk_raw: [u8; 33] = [
|
||||
0x03,
|
||||
0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,
|
||||
0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,
|
||||
0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,
|
||||
0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,0x40,
|
||||
];
|
||||
let input = EncInput {
|
||||
ss_bytes,
|
||||
epk_bytes: Bytes33::from(epk_raw),
|
||||
ipk_bytes: Bytes33::from(ipk_raw),
|
||||
commitment,
|
||||
out_index: 7,
|
||||
};
|
||||
|
||||
let env = ExecutorEnv::builder().write(&input)?.build()?;
|
||||
let prove_info = default_prover().prove(env, GUEST_ELF)?;
|
||||
let receipt = prove_info;
|
||||
let guest_ct = receipt.receipt.journal.bytes.clone();
|
||||
|
||||
|
||||
// Locally recomputes host ct (optional sanity check)
|
||||
let info = {
|
||||
let mut v = Vec::with_capacity(66 + 32);
|
||||
v.extend_from_slice(input.epk_bytes.as_ref());
|
||||
v.extend_from_slice(input.ipk_bytes.as_ref());
|
||||
v.extend_from_slice(&input.commitment);
|
||||
v
|
||||
};
|
||||
let k_enc = nssa_kdf(
|
||||
input.ss_bytes,
|
||||
input.epk_bytes.as_ref(),
|
||||
input.ipk_bytes.as_ref(),
|
||||
&input.commitment,
|
||||
input.out_index,
|
||||
);
|
||||
|
||||
let plaintext = b"hello";
|
||||
let host_ct = enc_xor_shake256(&k_enc, &info, plaintext);
|
||||
|
||||
println!("guest ct: {}", guest_ct.encode_hex::<String>());
|
||||
println!("host ct: {}", host_ct.encode_hex::<String>());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user