No Pod IDs (#394)
- middleware:
- Add `Statement::Intro`
- Add `SignedBy` native predicate and operation. The signature is auxiliary data to the operation
- Rename `PodSigner` to `Signer` with a new API (just for signing `RawValue`)
- Removed `NewEntry` operation. Use `ContainsFromEntries` instead
- Remove `KEY_SIGNER` and `KEY_TYPE` which are no longer used
- Merge `RecursivePod` and `Pod` traits
- Change the `Pod::deserialize_data` method to use `Self` instead of `Box<dyn Pod>`
- Extend `Pod` trait with these methods:
- `is_main`: when the pod is Main, in a (recursive) verification its vk will be checked to exist in the vd_set but not if it's intro pod
- `is_mock`: skip some verifications in the recursive mock MainPod verification
- `verifier_data_hash`
- `pod_id` renamed to `statements_hash`
- AnchoredKeys are now a pair of dictionary root and key
- Entry statements are now defined as Contains with literal arguments
- Operations that take Entries now use Contains statements with literal arguments
- frontend:
- Rename `SignedPod` to `SignedDict` (which now contains the dict, public key and signature, and can still `verify(self)`ed)
- The `SignedDict` keeps the method `get_statement` for convenience but now it returns a `Contains` statement that proves the existence of the key in the dict
- The `MainPodBuilder` automatically inserts a `Contains` statement when an operation is added that uses an entry as argument that was not yet "opened".
- Removed the `literal` methods from the `MainPodBuilder` that were loading literals to anchored keys: that was no longer needed after we introduced literal arguments
- backend
- Only verify inclusion of the verifying key into the vd_set if the pod is MainPod. A pod is not MainPod if the first statement is Intro.
- Reject intro pods that have non-intro statements
- Empty pod now returns an intro statement
- Don't insert a type statement automatically in MainPod and MockMainPod. We get rid of the type entry.
- Implement `SignedBy` operation, which uses the muxed table to store signature verifications
- Rename `PodId` to `statements_hash` or `sts_hash` for short. Now this is only used as a hash of the statements for the circuits public inputs.
- Refactor normalization of `self` statements:
- Before: replace values that contain `SELF` by the given pod_id
- After: place the verifying key hash into the Intro predicates
This commit is contained in:
parent
122f9c3cac
commit
0e2f7b756e
39 changed files with 2127 additions and 3064 deletions
|
|
@ -13,11 +13,11 @@ use std::env;
|
|||
use pod2::{
|
||||
backends::plonky2::{
|
||||
basetypes::DEFAULT_VD_SET, mainpod::Prover, mock::mainpod::MockProver,
|
||||
primitives::ec::schnorr::SecretKey, signedpod::Signer,
|
||||
primitives::ec::schnorr::SecretKey, signer::Signer,
|
||||
},
|
||||
frontend::{MainPodBuilder, Operation, SignedPodBuilder},
|
||||
frontend::{MainPodBuilder, Operation, SignedDictBuilder},
|
||||
lang::parse,
|
||||
middleware::{Params, PodProver, PodType, VDSet, Value, KEY_SIGNER, KEY_TYPE},
|
||||
middleware::{MainPodProver, Params, VDSet},
|
||||
};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
|
@ -34,7 +34,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
|
||||
let mock_prover = MockProver {};
|
||||
let real_prover = Prover {};
|
||||
let (vd_set, prover): (_, &dyn PodProver) = if mock {
|
||||
let (vd_set, prover): (_, &dyn MainPodProver) = if mock {
|
||||
(&VDSet::new(8, &[])?, &mock_prover)
|
||||
} else {
|
||||
println!("Prebuilding circuits to calculate vd_set...");
|
||||
|
|
@ -50,7 +50,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
let game_signer = Signer(game_sk);
|
||||
|
||||
// Build 2 signed pods where the game assigns points to a player that has completed a level.
|
||||
let mut builder = SignedPodBuilder::new(¶ms);
|
||||
let mut builder = SignedDictBuilder::new(¶ms);
|
||||
builder.insert("player", "Alice");
|
||||
builder.insert("level", 1);
|
||||
builder.insert("points", 3512);
|
||||
|
|
@ -58,7 +58,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
pod_points_lvl_1.verify()?;
|
||||
println!("# pod_points_lvl_1:\n{}", pod_points_lvl_1);
|
||||
|
||||
let mut builder = SignedPodBuilder::new(¶ms);
|
||||
let mut builder = SignedDictBuilder::new(¶ms);
|
||||
builder.insert("player", "Alice");
|
||||
builder.insert("level", 2);
|
||||
builder.insert("points", 5771);
|
||||
|
|
@ -71,12 +71,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
// Declare the custom predicate
|
||||
let input = format!(
|
||||
r#"
|
||||
points(player, level, points, private: points_pod) = AND(
|
||||
Equal(?points_pod["{key_type}"], {pod_type})
|
||||
Equal(?points_pod["{key_signer}"], {game_pk:#})
|
||||
Equal(?points_pod["player"], ?player)
|
||||
Equal(?points_pod["level"], ?level)
|
||||
Equal(?points_pod["points"], ?points)
|
||||
points(player, level, points, private: points_dict) = AND(
|
||||
SignedBy(?points_dict, PublicKey({game_pk}))
|
||||
Contains(?points_dict, "player", ?player)
|
||||
Contains(?points_dict, "level", ?level)
|
||||
Contains(?points_dict, "points", ?points)
|
||||
)
|
||||
|
||||
over_9000(player, private: points_lvl_1, points_lvl_2, points_total) = AND(
|
||||
|
|
@ -86,10 +85,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
Gt(?points_total, 9000)
|
||||
)
|
||||
"#,
|
||||
key_type = KEY_TYPE,
|
||||
key_signer = KEY_SIGNER,
|
||||
pod_type = PodType::Signed as usize,
|
||||
game_pk = Value::from(game_pk).raw(),
|
||||
game_pk = game_pk,
|
||||
);
|
||||
println!("# custom predicate batch:{}", input);
|
||||
let batch = parse(&input, ¶ms, &[])?.custom_batch;
|
||||
|
|
@ -98,37 +94,53 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
|
||||
// Build a pod to prove the statement `points("Alice", 1, 3512)`
|
||||
let mut builder = MainPodBuilder::new(¶ms, vd_set);
|
||||
builder.add_signed_pod(&pod_points_lvl_1);
|
||||
let st_type = builder.priv_op(Operation::eq(
|
||||
(&pod_points_lvl_1, KEY_TYPE),
|
||||
PodType::Signed,
|
||||
let st_signed_by = builder.priv_op(Operation::dict_signed_by(&pod_points_lvl_1))?;
|
||||
let st_player = builder.priv_op(Operation::dict_contains(
|
||||
pod_points_lvl_1.dict.clone(),
|
||||
"player",
|
||||
"Alice",
|
||||
))?;
|
||||
let st_level = builder.priv_op(Operation::dict_contains(
|
||||
pod_points_lvl_1.dict.clone(),
|
||||
"level",
|
||||
1,
|
||||
))?;
|
||||
let st_points = builder.priv_op(Operation::dict_contains(
|
||||
pod_points_lvl_1.dict.clone(),
|
||||
"points",
|
||||
3512,
|
||||
))?;
|
||||
let st_signer = builder.priv_op(Operation::eq((&pod_points_lvl_1, KEY_SIGNER), game_pk))?;
|
||||
let st_player = builder.priv_op(Operation::eq((&pod_points_lvl_1, "player"), "Alice"))?;
|
||||
let st_level = builder.priv_op(Operation::eq((&pod_points_lvl_1, "level"), 1))?;
|
||||
let st_points = builder.priv_op(Operation::eq((&pod_points_lvl_1, "points"), 3512))?;
|
||||
let st_points_lvl_1 = builder.pub_op(Operation::custom(
|
||||
points_pred.clone(),
|
||||
[st_type, st_signer, st_player, st_level, st_points],
|
||||
[st_signed_by, st_player, st_level, st_points],
|
||||
))?;
|
||||
|
||||
let pod_alice_lvl_1_points = builder.prove(prover).unwrap();
|
||||
println!("# pod_alice_lvl_1_points\n:{}", pod_alice_lvl_1_points);
|
||||
pod_alice_lvl_1_points.pod.verify().unwrap();
|
||||
|
||||
// Build a pod to prove the statement `points("Alice", 2, 5771)`
|
||||
let mut builder = MainPodBuilder::new(¶ms, vd_set);
|
||||
builder.add_signed_pod(&pod_points_lvl_2);
|
||||
let st_type = builder.priv_op(Operation::eq(
|
||||
(&pod_points_lvl_2, KEY_TYPE),
|
||||
PodType::Signed,
|
||||
let st_signed_by = builder.priv_op(Operation::dict_signed_by(&pod_points_lvl_2))?;
|
||||
let st_player = builder.priv_op(Operation::dict_contains(
|
||||
pod_points_lvl_2.dict.clone(),
|
||||
"player",
|
||||
"Alice",
|
||||
))?;
|
||||
let st_signer = builder.priv_op(Operation::eq((&pod_points_lvl_2, KEY_SIGNER), game_pk))?;
|
||||
let st_player = builder.priv_op(Operation::eq((&pod_points_lvl_2, "player"), "Alice"))?;
|
||||
let st_level = builder.priv_op(Operation::eq((&pod_points_lvl_2, "level"), 2))?;
|
||||
let st_points = builder.priv_op(Operation::eq((&pod_points_lvl_2, "points"), 5771))?;
|
||||
let st_level = builder.priv_op(Operation::dict_contains(
|
||||
pod_points_lvl_2.dict.clone(),
|
||||
"level",
|
||||
2,
|
||||
))?;
|
||||
let st_points = builder.priv_op(Operation::dict_contains(
|
||||
pod_points_lvl_2.dict.clone(),
|
||||
"points",
|
||||
5771,
|
||||
))?;
|
||||
|
||||
let st_points_lvl_2 = builder.pub_op(Operation::custom(
|
||||
points_pred,
|
||||
[st_type, st_signer, st_player, st_level, st_points],
|
||||
[st_signed_by, st_player, st_level, st_points],
|
||||
))?;
|
||||
let pod_alice_lvl_2_points = builder.prove(prover).unwrap();
|
||||
println!("# pod_alice_lvl_2_points\n:{}", pod_alice_lvl_2_points);
|
||||
|
|
@ -136,8 +148,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
|
||||
// Build a pod to prove the statement `over_9000("Alice")`
|
||||
let mut builder = MainPodBuilder::new(¶ms, vd_set);
|
||||
builder.add_recursive_pod(pod_alice_lvl_1_points);
|
||||
builder.add_recursive_pod(pod_alice_lvl_2_points);
|
||||
builder.add_pod(pod_alice_lvl_1_points);
|
||||
builder.add_pod(pod_alice_lvl_2_points);
|
||||
let st_points_total = builder.priv_op(Operation::sum_of(3512 + 5771, 3512, 5771))?;
|
||||
let st_gt_9000 = builder.priv_op(Operation::gt(3512 + 5771, 9000))?;
|
||||
let _st_over_9000 = builder.pub_op(Operation::custom(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue