Skip to content

Commit 3445bd9

Browse files
authored
feat: add middleware and signer traits (#18)
* feat: add middleware and signer traits * wip * wip * feat: MainPod traits
1 parent caa91cb commit 3445bd9

File tree

10 files changed

+826
-413
lines changed

10 files changed

+826
-413
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ itertools = "0.14.0"
1414
strum = "0.26"
1515
strum_macros = "0.26"
1616
anyhow = "1.0.56"
17+
dyn-clone = "1.0.18"

src/backend.rs

Lines changed: 6 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,15 @@
1+
// TODO: Move the SignedPod.id calculation to mock_signed
2+
// TODO: Move the MainPod logic to mock_main and implement the MainPod trait
3+
/*
14
use anyhow::Result;
25
use itertools::Itertools;
36
use plonky2::field::types::{Field, PrimeField64};
47
use std::collections::HashMap;
5-
use std::fmt;
68
use std::io::{self, Write};
79
use std::iter;
8-
use strum_macros::FromRepr;
910
10-
use crate::{merkletree::MerkleTree, Hash, Params, PodId, F, NULL};
11-
12-
#[derive(Clone, Copy, Debug, FromRepr, PartialEq, Eq)]
13-
pub enum NativeStatement {
14-
None = 0,
15-
ValueOf = 1,
16-
Equal = 2,
17-
NotEqual,
18-
Gt,
19-
Lt,
20-
Contains,
21-
NotContains,
22-
SumOf,
23-
ProductOf,
24-
MaxOf,
25-
}
26-
27-
#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq)]
28-
pub struct Value(pub [F; 4]);
29-
30-
impl fmt::Display for Value {
31-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32-
if self.0[2].is_zero() && self.0[3].is_zero() {
33-
// Assume this is an integer
34-
let (l0, l1) = (self.0[0].to_canonical_u64(), self.0[1].to_canonical_u64());
35-
assert!(l0 < (1 << 32));
36-
assert!(l1 < (1 << 32));
37-
write!(f, "{}", l0 + l1 * (1 << 32))
38-
} else {
39-
// Assume this is a hash
40-
Hash(self.0).fmt(f)
41-
}
42-
}
43-
}
44-
45-
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
46-
pub struct AnchoredKey(pub PodId, pub Hash);
47-
48-
#[derive(Clone, Debug, PartialEq, Eq)]
49-
pub enum StatementArg {
50-
None,
51-
Literal(Value),
52-
Ref(AnchoredKey),
53-
}
54-
55-
impl StatementArg {
56-
pub fn is_none(&self) -> bool {
57-
matches!(self, Self::None)
58-
}
59-
}
60-
61-
#[derive(Clone, Debug, PartialEq, Eq)]
62-
pub struct Statement(pub NativeStatement, pub Vec<StatementArg>);
63-
64-
impl Statement {
65-
pub fn is_none(&self) -> bool {
66-
matches!(self.0, NativeStatement::None)
67-
}
68-
}
11+
use crate::merkletree::MerkleTree;
12+
use crate::middleware::{Hash, Params, PodId, Value, NULL};
6913
7014
#[derive(Clone, Debug)]
7115
pub struct SignedPod {
@@ -306,3 +250,4 @@ mod tests {
306250
Ok(())
307251
}
308252
}
253+
*/

src/backends.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub mod mock_main;
2+
pub mod mock_signed;
3+
pub mod plonky2;

src/backends/mock_main.rs

Whitespace-only changes.

src/backends/mock_signed.rs

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
use crate::middleware::{
2+
hash_str, Hash, Params, PodId, PodSigner, PodType, SignedPod, Value, KEY_SIGNER, KEY_TYPE,
3+
};
4+
use itertools::Itertools;
5+
use std::any::Any;
6+
use std::collections::HashMap;
7+
8+
pub struct MockSigner {
9+
pub pk: String,
10+
}
11+
12+
fn calculate_pod_id(kvs: &HashMap<Hash, Value>) -> PodId {
13+
let mut s = String::new();
14+
for (k, v) in kvs.iter().sorted_by_key(|kv| kv.0) {
15+
s += &format!("{}:{},", k, v);
16+
}
17+
PodId(hash_str(&s))
18+
}
19+
20+
impl PodSigner for MockSigner {
21+
fn sign(&mut self, _params: &Params, kvs: &HashMap<Hash, Value>) -> Box<dyn SignedPod> {
22+
let mut kvs = kvs.clone();
23+
let pk_hash = hash_str(&self.pk);
24+
kvs.insert(hash_str(&KEY_SIGNER), Value(pk_hash.0));
25+
kvs.insert(hash_str(&KEY_TYPE), Value::from(PodType::MockSigned));
26+
27+
let id = calculate_pod_id(&kvs);
28+
let signature = format!("{}_signed_by_{}", id, pk_hash);
29+
Box::new(MockSignedPod {
30+
kvs: kvs.clone(),
31+
id,
32+
signature,
33+
})
34+
}
35+
}
36+
37+
#[derive(Clone, Debug)]
38+
pub struct MockSignedPod {
39+
pub id: PodId,
40+
pub signature: String,
41+
pub kvs: HashMap<Hash, Value>,
42+
}
43+
44+
impl SignedPod for MockSignedPod {
45+
fn verify(&self) -> bool {
46+
// Verify type
47+
if Some(&Value::from(PodType::MockSigned)) != self.kvs.get(&hash_str(&KEY_TYPE)) {
48+
return false;
49+
}
50+
51+
// Verify id
52+
let id = calculate_pod_id(&self.kvs);
53+
if id != self.id {
54+
return false;
55+
}
56+
57+
// Verify signature
58+
let pk_hash = match self.kvs.get(&hash_str(&KEY_SIGNER)) {
59+
Some(v) => v,
60+
None => return false,
61+
};
62+
let signature = format!("{}_signed_by_{}", id, pk_hash);
63+
if signature != self.signature {
64+
return false;
65+
}
66+
67+
return true;
68+
}
69+
70+
fn id(&self) -> PodId {
71+
self.id
72+
}
73+
74+
fn kvs(&self) -> HashMap<Hash, Value> {
75+
self.kvs.clone()
76+
}
77+
78+
fn into_any(self: Box<Self>) -> Box<dyn Any> {
79+
self
80+
}
81+
}
82+
83+
#[cfg(test)]
84+
pub mod tests {
85+
use super::*;
86+
use crate::frontend;
87+
use crate::middleware::{self, F, NULL};
88+
use plonky2::field::types::Field;
89+
90+
#[test]
91+
fn test_mock_signed_0() {
92+
let params = middleware::Params::default();
93+
let mut pod = frontend::SignedPodBuilder::new(&params);
94+
pod.insert("idNumber", "4242424242");
95+
pod.insert("dateOfBirth", 1169909384);
96+
pod.insert("socialSecurityNumber", "G2121210");
97+
98+
let mut signer = MockSigner { pk: "Molly".into() };
99+
let pod = pod.sign(&mut signer);
100+
let pod = pod.pod.into_any().downcast::<MockSignedPod>().unwrap();
101+
102+
assert_eq!(pod.verify(), true);
103+
println!("id: {}", pod.id());
104+
println!("kvs: {:?}", pod.kvs());
105+
106+
let mut bad_pod = pod.clone();
107+
bad_pod.signature = "".into();
108+
assert_eq!(bad_pod.verify(), false);
109+
110+
let mut bad_pod = pod.clone();
111+
bad_pod.id.0 .0[0] = F::ZERO;
112+
assert_eq!(bad_pod.verify(), false);
113+
114+
let mut bad_pod = pod.clone();
115+
bad_pod
116+
.kvs
117+
.insert(hash_str(KEY_SIGNER), Value(PodId(NULL).0 .0));
118+
assert_eq!(bad_pod.verify(), false);
119+
120+
let mut bad_pod = pod.clone();
121+
bad_pod.kvs.insert(hash_str(KEY_TYPE), Value::from(0));
122+
assert_eq!(bad_pod.verify(), false);
123+
}
124+
}

src/backends/plonky2.rs

Whitespace-only changes.

0 commit comments

Comments
 (0)