#!/bin/bash # Test SUP-03: Padding Payload Handling # Tests: Type 2 payload with padding bytes and double decryption set -e TEST_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$TEST_DIR/helpers/timing_utils.sh" source "$TEST_DIR/helpers/event_utils.sh" # Load test configuration KEYS_FILE="$TEST_DIR/fixtures/test_keys.json" RELAYS_FILE="$TEST_DIR/fixtures/test_relays.json" # Extract keys BUILDER_PRIVKEY=$(jq -r '.builder.privkey' "$KEYS_FILE") THROWER_A_PRIVKEY=$(jq -r '.thrower_a.privkey' "$KEYS_FILE") THROWER_A_PUBKEY=$(jq -r '.thrower_a.pubkey' "$KEYS_FILE") THROWER_B_PRIVKEY=$(jq -r '.thrower_b.privkey' "$KEYS_FILE") THROWER_B_PUBKEY=$(jq -r '.thrower_b.pubkey' "$KEYS_FILE") # Extract relays THROWER_A_RELAY=$(jq -r '.test_scenarios.multi_hop_2.thrower_a_relay' "$RELAYS_FILE") THROWER_B_RELAY=$(jq -r '.test_scenarios.multi_hop_2.thrower_b_relay' "$RELAYS_FILE") FINAL_RELAY=$(jq -r '.test_scenarios.multi_hop_2.final_relay' "$RELAYS_FILE") echo "=== SUP-03: Padding Payload Test ===" echo "Thrower A: $THROWER_A_PUBKEY → $THROWER_A_RELAY" echo "Thrower B: $THROWER_B_PUBKEY → $THROWER_B_RELAY" echo "Final Relay: $FINAL_RELAY" echo "" # Test parameters DELAY_A=2 DELAY_B=2 PADDING_BYTES=1024 AUDIT_TAG="test-padding-$(date +%s)" TEST_CONTENT="Padding test message at $(date)" echo "Step 1: Create inner kind 1 event" INNER_EVENT=$(create_test_event "$BUILDER_PRIVKEY" "$TEST_CONTENT") INNER_EVENT_ID=$(echo "$INNER_EVENT" | jq -r '.id') echo "Created inner event: $INNER_EVENT_ID" echo "" echo "Step 2: Create routing payload for Thrower B (final hop)" ROUTING_B=$(create_routing_payload "$INNER_EVENT" "$FINAL_RELAY" "$DELAY_B" "null" "$AUDIT_TAG") ENCRYPTED_B=$(encrypt_payload "$BUILDER_PRIVKEY" "$THROWER_B_PUBKEY" "$ROUTING_B") WRAPPER_B=$(create_routing_event "$BUILDER_PRIVKEY" "$THROWER_B_PUBKEY" "$ENCRYPTED_B") echo "Created routing for Thrower B" echo "" echo "Step 3: Create routing payload for Thrower A WITH PADDING INSTRUCTION" echo "Instructing Thrower A to add ${PADDING_BYTES} bytes of padding" ROUTING_A=$(create_routing_payload "$WRAPPER_B" "$THROWER_B_RELAY" "$DELAY_A" "$THROWER_B_PUBKEY" "$AUDIT_TAG" "$PADDING_BYTES") echo "" # Verify padding instruction is in the payload if ! echo "$ROUTING_A" | grep -q "add_padding_bytes"; then echo "ERROR: Padding instruction not found in routing payload" exit 1 fi echo "✓ Padding instruction included: add_padding_bytes=$PADDING_BYTES" echo "" echo "Step 4: Encrypt and wrap for Thrower A" ENCRYPTED_A=$(encrypt_payload "$BUILDER_PRIVKEY" "$THROWER_A_PUBKEY" "$ROUTING_A") WRAPPER_A=$(create_routing_event "$BUILDER_PRIVKEY" "$THROWER_A_PUBKEY" "$ENCRYPTED_A") WRAPPER_A_ID=$(echo "$WRAPPER_A" | jq -r '.id') echo "Created routing event: $WRAPPER_A_ID" echo "" echo "Step 5: Publish to Thrower A" PUBLISH_TIME=$(get_timestamp) publish_event "$WRAPPER_A" "$THROWER_A_RELAY" echo "Published at: $(date -d @$PUBLISH_TIME)" echo "" echo "Step 6: Monitor for intermediate event on Thrower B's relay" echo "This event should be a Type 2 payload (with padding)" echo "Monitoring $THROWER_B_RELAY for kind 22222 events to Thrower B..." echo "" # Wait for Thrower A to process and forward sleep $((DELAY_A + 5)) # Try to find the forwarded event on Thrower B's relay # This is tricky because we need to find kind 22222 events with p-tag for Thrower B INTERMEDIATE_FOUND=false INTERMEDIATE_EVENT=$(nak req --relay "$THROWER_B_RELAY" -k 22222 --tag "p,$THROWER_B_PUBKEY" --limit 10 --timeout 5 2>/dev/null | \ jq -s 'sort_by(.created_at) | reverse | .[0]' 2>/dev/null || echo "{}") if [ "$(echo "$INTERMEDIATE_EVENT" | jq -r '.id')" != "null" ] && [ "$(echo "$INTERMEDIATE_EVENT" | jq -r '.id')" != "" ]; then INTERMEDIATE_FOUND=true INTERMEDIATE_ID=$(echo "$INTERMEDIATE_EVENT" | jq -r '.id') echo "✓ Found intermediate event: $INTERMEDIATE_ID" # Check size - should be larger due to padding INTERMEDIATE_SIZE=$(echo "$INTERMEDIATE_EVENT" | jq -r '.content' | wc -c) echo " Intermediate event content size: ${INTERMEDIATE_SIZE} bytes" echo " (Should be larger than original due to padding)" else echo "⚠ Could not verify intermediate event (may have been processed already)" fi echo "" echo "Step 7: Monitor for final event on destination relay" echo "Monitoring $FINAL_RELAY for inner event $INNER_EVENT_ID..." echo "" TIMEOUT=$((DELAY_A + DELAY_B + 30)) FOUND=false START_MONITOR=$(get_timestamp) while [ $(($(get_timestamp) - START_MONITOR)) -lt $TIMEOUT ]; do if query_event "$INNER_EVENT_ID" "$FINAL_RELAY" 2 | grep -q "$INNER_EVENT_ID"; then ARRIVAL_TIME=$(get_timestamp) FOUND=true break fi sleep 1 done if [ "$FOUND" = false ]; then echo "ERROR: Inner event not found on final relay within ${TIMEOUT}s" echo "This indicates:" echo " - Thrower A may not have added padding correctly" echo " - Thrower B may not have handled Type 2 payload correctly" echo " - Double decryption may have failed" exit 1 fi echo "✓ Inner event found on final relay" echo "" echo "Step 8: Verify timing" ACTUAL_DELAY=$((ARRIVAL_TIME - PUBLISH_TIME)) EXPECTED_DELAY=$((DELAY_A + DELAY_B)) echo "Actual delay: ${ACTUAL_DELAY}s" echo "Expected minimum: ${EXPECTED_DELAY}s" if [ $ACTUAL_DELAY -lt $EXPECTED_DELAY ]; then echo "ERROR: Event arrived too early!" exit 1 fi echo "" echo "Step 9: Verify event content" FINAL_EVENT=$(query_event "$INNER_EVENT_ID" "$FINAL_RELAY" 5) FINAL_CONTENT=$(echo "$FINAL_EVENT" | jq -r '.content') if [ "$FINAL_CONTENT" != "$TEST_CONTENT" ]; then echo "ERROR: Content mismatch!" echo "Expected: $TEST_CONTENT" echo "Got: $FINAL_CONTENT" exit 1 fi echo "Content verified: $FINAL_CONTENT" echo "" echo "=== TEST PASSED ===" echo "✓ Padding instruction processed by Thrower A" echo "✓ Type 2 payload created with ${PADDING_BYTES} bytes padding" echo "✓ Thrower B performed double decryption" echo "✓ Padding discarded correctly" echo "✓ Inner event delivered successfully" echo "✓ Content preserved through padding layer" echo "" echo "Key Observations:" if [ "$INTERMEDIATE_FOUND" = true ]; then echo " - Intermediate event size increased due to padding" fi echo " - Double decryption handled correctly" echo " - Timing constraints respected" echo "" exit 0