Advanced Software-Defined Signatures
Beyond the built-in ZK and SECP256K1 signature schemes, Psy enables truly programmable authentication through custom zero-knowledge circuits. This allows developers to implement sophisticated signing logic with transaction introspection capabilities.
Extended Software-Defined Keys
Concept
Software-defined signatures enable authentication schemes that go beyond simple cryptographic signatures. Users can define custom circuits that implement complex authorization logic.
Basic Extended Signature
Using Psy Language:
#[software_defined_signature]
pub fn basic_constraint_auth(
secret: Felt,
contract_id: Felt,
method_id: Felt,
inputs: &[Felt],
) -> bool {
// Verify knowledge of secret (any unique identifier)
let computed_identifier = hash(secret);
let secret_valid = computed_identifier == EXPECTED_IDENTIFIER;
// Constrain contract and method
let contract_valid = contract_id == 0;
let method_valid = method_id == 0;
let input_valid = inputs[0] < 500;
secret_valid && contract_valid && method_valid && input_valid
}
Using DPNSoftwareDefinedCallData:
#![allow(unused)] fn main() { // Deploy the circuit let call_data = DPNSoftwareDefinedCallData { contract_id: 0, inputs: vec![amount, param1, param2], // amount must be < 500 }; }
Key Features:
- Flexible Authentication: Authentication not tied to traditional private keys
- Transaction Constraints: Circuits can constrain transaction parameters
- Public Authorization: Can implement publicly verifiable authorization logic
Use Case: Matching Bot
Automated Market Making
A sophisticated use case is implementing an automated order matching system:
Using Psy Language for Order Matching:
#[software_defined_signature]
pub fn order_matching_auth(
contract_id: Felt,
method_name: &str,
inputs: &[Felt],
buy_orders_proof: MerkleProof,
sell_orders_proof: MerkleProof,
checkpoint_data: CheckpointData,
) -> bool {
// Verify this is the expected protocol
let protocol_valid = hash("QEDProtocol") == EXPECTED_PROTOCOL_HASH;
assert(protocol_valid);
// Only allow order matching contract
let contract_valid = contract_id == ORDER_BOOK_CONTRACT_ID;
assert(contract_valid);
// Only allow match_orders method
let method_valid = method_name == "match_orders";
assert(method_valid);
// Verify merkle proofs against checkpoint
let buy_proof_valid = verify_merkle_proof(&checkpoint_data.tree_root, &buy_orders_proof);
let sell_proof_valid = verify_merkle_proof(&checkpoint_data.tree_root, &sell_orders_proof);
assert(buy_proof_valid && sell_proof_valid);
// Extract order data from proofs
let buy_orders = extract_orders_from_proof(&buy_orders_proof);
let sell_orders = extract_orders_from_proof(&sell_orders_proof);
// Implement optimal matching logic
let (best_buy_index, best_sell_index) = find_optimal_match(&buy_orders, &sell_orders);
// Verify the inputs match the optimal selection
inputs[0] == best_buy_index && inputs[1] == best_sell_index
}
// Helper functions that would be available in the circuit
fn find_optimal_match(buy_orders: &[Order], sell_orders: &[Order]) -> (Felt, Felt) {
// Implement matching algorithm ensuring best price execution
let mut best_spread = Felt::MAX;
let mut best_pair = (0, 0);
for (i, buy_order) in buy_orders.iter().enumerate() {
for (j, sell_order) in sell_orders.iter().enumerate() {
if buy_order.price >= sell_order.price {
let spread = buy_order.price - sell_order.price;
if spread < best_spread {
best_spread = spread;
best_pair = (i as Felt, j as Felt);
}
}
}
}
best_pair
}
Deployment and Usage:
#![allow(unused)] fn main() { // Register the matching bot circuit let fingerprint = circuit_manager .register_dpn_software_defined_circuit( order_matching_auth_bytecode, 32, // contract_state_tree_height ) .await?; // Anyone can now trigger optimal order matching let call_data = DPNSoftwareDefinedCallData { contract_id: ORDER_BOOK_CONTRACT_ID, inputs: vec![buy_order_index, sell_order_index], }; }
Capabilities:
- State Access: Circuits can read and verify on-chain state
- Algorithmic Trading: Implement complex matching algorithms in ZK
- Trustless Automation: No need to trust the bot operator
- Optimal Execution: Prove optimal order matching on-chain
Advanced Applications
1. Permissionless Bots
#[software_defined_signature]
pub fn permissionless_bot_auth(
contract_id: Felt,
method_name: &str,
inputs: &[Felt],
) -> bool {
// No secret required - anyone can execute
// But execution is constrained by logic
// Verify bot identifier
let bot_id = hash("PermissionlessBot");
let bot_valid = bot_id == EXPECTED_BOT_IDENTIFIER;
assert(bot_valid);
// Only allow specific method
let method_valid = method_name == "allowed_method";
assert(method_valid);
// Minimum threshold constraint
inputs[0] > MIN_THRESHOLD
}
Use Cases:
- Liquidation Bots: Anyone can liquidate, but only valid liquidations
- Arbitrage Bots: Permissionless arbitrage with guaranteed profitability
- Rebalancing: Portfolio rebalancing with constraints
2. Conditional Execution
#[software_defined_signature]
pub fn conditional_spending_auth(
contract_id: Felt,
inputs: &[Felt],
balance_proof: MerkleProof,
checkpoint_data: CheckpointData,
) -> bool {
// Verify user balance from merkle proof
let balance_proof_valid = verify_merkle_proof(&checkpoint_data.tree_root, &balance_proof);
assert(balance_proof_valid);
let user_balance = extract_balance_from_proof(&balance_proof);
// Only allow transaction if balance > threshold
let balance_sufficient = user_balance > 1000;
assert(balance_sufficient);
// Constrain transaction amount to max 50% of balance
let transaction_amount = inputs[0];
transaction_amount <= user_balance / 2
}
Use Cases:
- Spending Limits: Enforce spending limits in the signature
- Time Locks: Implement time-based restrictions
- Multi-Factor: Require multiple secrets or conditions
3. Cross-Chain Verification
#[software_defined_signature]
pub fn cross_chain_collateral_auth(
contract_id: Felt,
inputs: &[Felt],
ethereum_proof: EthereumStateProof,
bridge_data: BridgeVerificationData,
) -> bool {
// Verify state from Ethereum blockchain
let eth_proof_valid = verify_ethereum_state_proof(ðereum_proof, &bridge_data);
assert(eth_proof_valid);
// Extract user's Ethereum balance
let ethereum_balance = extract_balance_from_eth_proof(ðereum_proof);
let required_collateral = MINIMUM_COLLATERAL_RATIO;
// Constrain based on external state
let collateral_sufficient = ethereum_balance > required_collateral;
assert(collateral_sufficient);
// Allow transaction only if collateral is sufficient
let transaction_amount = inputs[0];
transaction_amount <= ethereum_balance
}
Ultra-Programmable Signatures
Nested Circuit Architecture
The ultimate evolution enables arbitrary computation within signatures:
QED Software Defined Signature (Ultra):
public_key_params = hash(QEDProtocol)
fingerprint = hash(verifier_data)
public_key = hash(public_key_params, fingerprint)
sig_action_hash = hash(data, network_magic, nonce)
circuit = {
let inner_circuit = compile(verify_balance_gt_zero)
verify_inner_circuit(private_inputs, public_inputs)
}
public_inputs = hash(public_key_params, sig_action_hash)
private_inputs = sig_action_hash_preimage
High-Level Programming
Users can write signature logic in high-level languages:
#![allow(unused)] fn main() { // Rust function compiled to ZK circuit fn verify_balance_gt_zero(user_leaf: UserLeaf) -> bool { user_leaf.balance > 0 } // Complex authorization logic fn advanced_authorization( user_leaf: UserLeaf, contract_call: ContractCall, checkpoint_data: CheckpointData ) -> bool { // Implement sophisticated authorization logic user_leaf.balance > contract_call.amount && checkpoint_data.timestamp > user_leaf.last_transaction + cooldown_period && contract_call.method_id.is_whitelisted() } }
Capabilities:
- Rust Integration: Write circuits in Rust using macros
- VM Integration: Embed ZKVM for arbitrary computation
- Nested Proofs: Compose multiple proof systems
- Code Reuse: Share and reuse authorization components
Implementation Patterns
1. Account Types
EOA (Externally Owned Account):
- Uses traditional private key signatures
- Simple authentication model
- Direct user control
SDA (Software Defined Account):
- Uses programmable circuit-based signatures
- Complex authorization logic
- Automated or conditional execution
2. Circuit Management
Off-Chain Storage:
# Circuits are managed off-chain by users
.signatures/
├── matching_bot.circuit
├── conditional_spending.circuit
└── multi_factor.circuit
Fingerprint Mapping:
#![allow(unused)] fn main() { // Map fingerprints to circuit definitions let circuit = load_circuit_by_fingerprint(user_public_key.fingerprint)?; let proof = generate_signature_proof(circuit, private_inputs)?; }
3. Security Model
Public Key Composition:
public_key_params: Circuit-specific identifierfingerprint: Hash of circuit verifier datapublic_key: Combined hash for on-chain storage
Privacy Guarantees:
- Circuit logic remains private (off-chain)
- Only fingerprint is public (on-chain)
- Zero-knowledge proofs don't reveal circuit internals
Development Workflow
1. Circuit Development
#![allow(unused)] fn main() { // Write authorization logic #[signature_circuit] fn my_authorization_logic( secret: PrivateInput<F>, call_data: CallData, checkpoint: CheckpointData, ) -> PublicOutput<F> { // Implement custom authorization } }
2. Deployment
# Compile circuit
psy_compiler compile-signature-circuit my_auth.rs
# Register circuit fingerprint
psy_user_cli register-user --circuit-fingerprint <fingerprint>
3. Usage
# Sign transaction with custom circuit
psy_user_cli call \
--signature-circuit my_auth.circuit \
--private-inputs secret.json \
--contract-id 0 \
--method-name transfer
Future Directions
1. Circuit Marketplace
- Shared Circuits: Community-developed authorization patterns
- Audited Components: Verified and audited circuit modules
- Composable Logic: Mix and match authorization components
2. Hardware Integration
- Hardware Wallets: Support for complex circuits in hardware
- Secure Enclaves: Trusted execution for sensitive authorization logic
- Mobile Optimization: Efficient circuits for mobile devices
3. Cross-Chain Integration
- Bridge Verification: Verify state from other blockchains
- Multi-Chain Auth: Authorization spanning multiple networks
- Interoperability: Standard interfaces for cross-chain circuits
Software-defined signatures represent a fundamental shift from fixed cryptographic primitives to programmable authentication systems, enabling new classes of applications and user experiences.