Secret keys in Podlang (#365)

This commit is contained in:
Rob Knight 2025-07-29 23:50:10 +01:00 committed by GitHub
parent ce8cabc337
commit 59c6151dbc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 64 additions and 9 deletions

View file

@ -60,6 +60,7 @@ anchored_key = { wildcard ~ "[" ~ literal_string ~ "]" }
// Literal Values (ordered to avoid ambiguity, e.g., string before int) // Literal Values (ordered to avoid ambiguity, e.g., string before int)
literal_value = { literal_value = {
literal_public_key | literal_public_key |
literal_secret_key |
literal_dict | literal_dict |
literal_set | literal_set |
literal_array | literal_array |
@ -95,6 +96,11 @@ base58_char = { '1'..'9' | 'A'..'H' | 'J'..'N' | 'P'..'Z' | 'a'..'k' | 'm'..'z'
base58_string = @{ base58_char+ } base58_string = @{ base58_char+ }
literal_public_key = { "PublicKey" ~ "(" ~ base58_string ~ ")" } literal_public_key = { "PublicKey" ~ "(" ~ base58_string ~ ")" }
// SecretKey(...)
base64_char = { 'a'..'z' | 'A'..'Z' | '0'..'9' | "+" | "/" | "=" }
base64_string = @{ base64_char+ }
literal_secret_key = { "SecretKey" ~ "(" ~ base64_string ~ ")" }
// Container Literals (recursive definition using literal_value) // Container Literals (recursive definition using literal_value)
literal_array = { "[" ~ (literal_value ~ ("," ~ literal_value)*)? ~ "]" } literal_array = { "[" ~ (literal_value ~ ("," ~ literal_value)*)? ~ "]" }
literal_set = { "#[" ~ (literal_value ~ ("," ~ literal_value)*)? ~ "]" } literal_set = { "#[" ~ (literal_value ~ ("," ~ literal_value)*)? ~ "]" }

View file

@ -29,6 +29,7 @@ mod tests {
use super::*; use super::*;
use crate::{ use crate::{
backends::plonky2::primitives::ec::schnorr::SecretKey,
lang::error::ProcessorError, lang::error::ProcessorError,
middleware::{ middleware::{
hash_str, CustomPredicate, CustomPredicateBatch, CustomPredicateRef, Key, hash_str, CustomPredicate, CustomPredicateBatch, CustomPredicateRef, Key,
@ -859,25 +860,32 @@ mod tests {
#[test] #[test]
fn test_e2e_literals() -> Result<(), LangError> { fn test_e2e_literals() -> Result<(), LangError> {
let pk = crate::backends::plonky2::primitives::ec::curve::Point::generator(); let pk = crate::backends::plonky2::primitives::ec::curve::Point::generator();
let pk_b58 = pk.to_string();
let pod_id = PodId(hash_str("test")); let pod_id = PodId(hash_str("test"));
let raw = RawValue::from(1); let raw = RawValue::from(1);
let string = "hello"; let string = "hello";
let int = 123; let int = 123;
let bool = true; let bool = true;
let sk = SecretKey::new_rand();
let input = format!( let input = format!(
r#" r#"
REQUEST( REQUEST(
Equal(?A["pk"], PublicKey({})) Equal(?A["pk"], {})
Equal(?B["pod_id"], {:#}) Equal(?B["pod_id"], {})
Equal(?C["raw"], Raw({:#})) Equal(?C["raw"], {})
Equal(?D["string"], "{}") Equal(?D["string"], {})
Equal(?E["int"], {}) Equal(?E["int"], {})
Equal(?F["bool"], {}) Equal(?F["bool"], {})
Equal(?G["sk"], {})
) )
"#, "#,
pk_b58, pod_id, raw, string, int, bool Value::from(pk).to_podlang_string(),
Value::from(pod_id).to_podlang_string(),
Value::from(raw).to_podlang_string(),
Value::from(string).to_podlang_string(),
Value::from(int).to_podlang_string(),
Value::from(bool).to_podlang_string(),
Value::from(sk.clone()).to_podlang_string()
); );
/* /*
REQUEST( REQUEST(
@ -894,7 +902,7 @@ mod tests {
let processed = parse(&input, &params, &[])?; let processed = parse(&input, &params, &[])?;
let request_templates = processed.request_templates; let request_templates = processed.request_templates;
assert_eq!(request_templates.len(), 6); assert_eq!(request_templates.len(), 7);
let expected_templates = vec![ let expected_templates = vec![
StatementTmpl { StatementTmpl {
@ -921,6 +929,10 @@ mod tests {
pred: Predicate::Native(NativePredicate::Equal), pred: Predicate::Native(NativePredicate::Equal),
args: vec![sta_ak(("F", 5), "bool"), sta_lit(Value::from(bool))], args: vec![sta_ak(("F", 5), "bool"), sta_lit(Value::from(bool))],
}, },
StatementTmpl {
pred: Predicate::Native(NativePredicate::Equal),
args: vec![sta_ak(("G", 6), "sk"), sta_lit(Value::from(sk))],
},
]; ];
assert_eq!(request_templates, expected_templates); assert_eq!(request_templates, expected_templates);

View file

@ -192,6 +192,7 @@ fn fmt_predicate_signature(
mod tests { mod tests {
use super::*; use super::*;
use crate::{ use crate::{
backends::plonky2::primitives::ec::schnorr::SecretKey,
lang::parse, lang::parse,
middleware::{ middleware::{
CustomPredicate, Key, NativePredicate, Params, Predicate, StatementTmpl, CustomPredicate, Key, NativePredicate, Params, Predicate, StatementTmpl,
@ -492,6 +493,20 @@ mod tests {
assert_round_trip(input); assert_round_trip(input);
} }
#[test]
fn test_round_trip_secret_key() {
let sk = SecretKey::new_rand();
let input = format!(
r#"
secret_key_test(Pod) = AND(
Equal(?Pod["sk"], {})
)
"#,
Value::from(sk.clone()).to_podlang_string()
);
assert_round_trip(&input);
}
#[test] #[test]
fn test_pretty_print_demonstration() { fn test_pretty_print_demonstration() {
let input = r#" let input = r#"

View file

@ -8,9 +8,12 @@ use plonky2::field::types::Field;
use super::error::ProcessorError; use super::error::ProcessorError;
use crate::{ use crate::{
backends::plonky2::primitives::ec::curve::Point, backends::plonky2::{
deserialize_bytes,
primitives::ec::{curve::Point, schnorr::SecretKey},
},
frontend::{BuilderArg, CustomPredicateBatchBuilder, StatementTmplBuilder}, frontend::{BuilderArg, CustomPredicateBatchBuilder, StatementTmplBuilder},
lang::parser::Rule, lang::Rule,
middleware::{ middleware::{
self, CustomPredicateBatch, CustomPredicateRef, Key, NativePredicate, Params, Predicate, self, CustomPredicateBatch, CustomPredicateRef, Key, NativePredicate, Params, Predicate,
StatementTmpl, StatementTmplArg, Value, Wildcard, F, VALUE_SIZE, StatementTmpl, StatementTmplArg, Value, Wildcard, F, VALUE_SIZE,
@ -795,6 +798,25 @@ fn process_literal_value(
})?; })?;
Ok(Value::from(middleware_dict)) Ok(Value::from(middleware_dict))
} }
Rule::literal_secret_key => {
let sk_str_pair = inner_lit.clone().into_inner().next().unwrap();
let sk_base64 = sk_str_pair.as_str();
let bytes = deserialize_bytes(sk_base64).map_err(|_e| {
ProcessorError::InvalidLiteralFormat {
kind: "SecretKey".to_string(),
value: sk_base64.to_string(),
span: Some(get_span(&inner_lit)),
}
})?;
let secret_key = SecretKey::from_bytes(&bytes).map_err(|_e| {
ProcessorError::InvalidLiteralFormat {
kind: "SecretKey".to_string(),
value: sk_base64.to_string(),
span: Some(get_span(&inner_lit)),
}
})?;
Ok(Value::from(secret_key))
}
_ => unreachable!("Unexpected rule: {:?}", inner_lit.as_rule()), _ => unreachable!("Unexpected rule: {:?}", inner_lit.as_rule()),
} }
} }