Skip to content
This repository was archived by the owner on Oct 16, 2024. It is now read-only.

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
gubsheep committed Oct 2, 2024
1 parent 5e7a318 commit 0255179
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 9 deletions.
132 changes: 127 additions & 5 deletions src/pod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,66 @@ use plonky2::plonk::config::GenericHashOut;
use plonky2::plonk::config::Hasher;
use util::hash_string_to_field;

use crate::schnorr::SchnorrPublicKey;
use crate::schnorr::SchnorrSecretKey;
use crate::schnorr::SchnorrSignature;
use crate::schnorr::SchnorrSigner;

use rand;
use rand::Rng;

mod util;

pub trait EntryValue: Clone {
pub(crate) type Error = Box<dyn std::error::Error>;

pub trait HashablePayload: Clone + PartialEq {
fn to_field_vec(&self) -> Vec<GoldilocksField>;
fn hash_payload(&self) -> GoldilocksField;
}

impl<V: EntryValue> HashablePayload for Vec<Entry<V>> {
fn to_field_vec(&self) -> Vec<GoldilocksField> {
let mut sorted_by_key_name = self.clone();
sorted_by_key_name.sort_by(|a, b| a.key_name.cmp(&b.key_name));
let mut ins = Vec::new();
sorted_by_key_name.iter().for_each(|entry| {
ins.push(entry.key_hash);
ins.push(entry.value_hash);
});
ins
}

fn hash_payload(&self) -> GoldilocksField {
let ins = self.to_field_vec();
PoseidonHash::hash_no_pad(&ins).to_vec()[0]
}
}

pub trait ProofOf<Payload>: Clone {
fn verify(&self, payload: &Payload) -> Result<bool, Error>;
}

impl ProofOf<Vec<Entry<ScalarOrVec>>> for SchnorrSignature {
fn verify(&self, payload: &Vec<Entry<ScalarOrVec>>) -> Result<bool, Error> {
let payload_vec = payload.to_field_vec();
let protocol = SchnorrSigner::new();
let wrapped_pk = payload
.iter()
.filter(|entry| entry.key_name == "_signer")
.collect::<Vec<&Entry<ScalarOrVec>>>();
if wrapped_pk.len() == 0 {
return Err("No signer found in payload".into());
}

let pk = match wrapped_pk[0].value {
ScalarOrVec::Vector(_) => Err(Error::from("Signer is a vector")),
ScalarOrVec::Scalar(s) => Ok(s),
}?;
Ok(protocol.verify(&self, &payload_vec, &SchnorrPublicKey { pk }))
}
}

pub trait EntryValue: Clone + PartialEq {
fn hash_or_value(&self) -> GoldilocksField;
}

Expand All @@ -23,7 +80,23 @@ impl EntryValue for Vec<GoldilocksField> {
}
}

#[derive(Clone, Debug, PartialEq)]
pub enum ScalarOrVec {
Scalar(GoldilocksField),
Vector(Vec<GoldilocksField>),
}

impl EntryValue for ScalarOrVec {
fn hash_or_value(&self) -> GoldilocksField {
match self {
Self::Scalar(s) => s.hash_or_value(),
Self::Vector(v) => v.hash_or_value(),
}
}
}

#[derive(Copy, Clone, Debug, PartialEq)]
#[repr(usize)]
pub enum GadgetID {
NONE = 0,
SCHNORR16 = 1,
Expand All @@ -36,7 +109,7 @@ pub struct Origin {
pub gadget_id: Option<GadgetID>, // if origin_id is SELF, this is none; otherwise, it's the gadget_id
}

#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
pub struct Entry<V: EntryValue> {
pub key_name: String,
pub key_hash: GoldilocksField,
Expand Down Expand Up @@ -75,6 +148,52 @@ pub struct Statement {
pub optional_value: Option<GoldilocksField>,
}

#[derive(Clone, Debug, PartialEq)]
pub struct POD<Payload: HashablePayload, Proof: ProofOf<Payload>, const FromGadgetID: usize> {
pub payload: Payload,
proof: Proof,
}

type SchnorrPOD = POD<Vec<Entry<ScalarOrVec>>, SchnorrSignature, { GadgetID::SCHNORR16 as usize }>;

type GODPOD = POD<Vec<Entry<ScalarOrVec>>, SchnorrSignature, { GadgetID::GOD as usize }>;

#[derive(Clone, Debug, PartialEq)]
pub enum SchnorrOrGODPOD {
SchnorrPOD(SchnorrPOD),
GODPOD(GODPOD),
}

impl<Payload: HashablePayload, Proof: ProofOf<Payload>, const FromGadgetID: usize>
POD<Payload, Proof, FromGadgetID>
{
pub fn verify(&self) -> Result<bool, Error> {
self.proof.verify(&self.payload)
}
}

impl SchnorrPOD {
pub fn new(entries: &Vec<Entry<ScalarOrVec>>, sk: &SchnorrSecretKey) -> Self {
let mut rng: rand::rngs::ThreadRng = rand::thread_rng();
let protocol = SchnorrSigner::new();

let mut payload = entries.clone();
payload.push(Entry::new(
"_signer",
ScalarOrVec::Scalar(protocol.keygen(sk).pk),
));
let payload_vec = entries.to_field_vec();
let proof = protocol.sign(&payload_vec, sk, &mut rng);
Self { payload, proof }
}
}

impl GODPOD {
pub fn from_pods(inputs: &Vec<SchnorrOrGODPOD>, operations: &Vec<Operation>) -> Self {
let mut payload = Vec::new();
}
}

#[derive(Copy, Clone, Debug)]
pub enum Operation {
None = 0,
Expand Down Expand Up @@ -369,7 +488,10 @@ fn op_test() {
let mut expected_statement = unwrapped_gt_statement.clone();
expected_statement.predicate = StatementPredicate::NotEqual;
assert!(
Operation::GtToNonequality.apply_operation::<GoldilocksField>(Some(&unwrapped_gt_statement), None, None)
== Some(expected_statement)
);
Operation::GtToNonequality.apply_operation::<GoldilocksField>(
Some(&unwrapped_gt_statement),
None,
None
) == Some(expected_statement)
);
}
8 changes: 4 additions & 4 deletions src/schnorr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,24 @@ const BIG_GROUP_GEN: GoldilocksField = GoldilocksField(14293326489335486720);
// 8-bit security (i.e. totally insecure, DO NOT USE if you want any security at all)
// because it uses the multiplicative group of the Goldilocks field

#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct SchnorrSigner {
PRIME_GROUP_GEN: GoldilocksField,
PRIME_GROUP_ORDER: u64,
}

#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq)]

pub struct SchnorrSecretKey {
pub sk: u64,
}

#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct SchnorrPublicKey {
pub pk: GoldilocksField,
}

#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct SchnorrSignature {
pub s: u64,
pub e: u64,
Expand Down

0 comments on commit 0255179

Please sign in to comment.