3030#include < vm/secure_zero.hpp>
3131
3232#include < cstring>
33- #include < vector>
3433
3534namespace VMPilot ::Runtime::pipeline {
3635
@@ -63,13 +62,13 @@ static uint64_t update_enc_state_impl(uint64_t enc_state,
6362 return siphash_2_4 (key, msg, 8 );
6463}
6564
66- // / Find BB index by bb_id (linear search -- v1 simplicity).
65+ // / Find BB index by bb_id — O(1) dense vector lookup (P2).
66+ // / Returns -1 for unknown bb_id (same semantics as the original linear scan).
6767static int find_bb_index (const VmImmutable& imm, uint32_t bb_id) noexcept {
68- for (size_t i = 0 ; i < imm.bb_metadata .size (); ++i) {
69- if (imm.bb_metadata [i].bb_id == bb_id)
70- return static_cast <int >(i);
71- }
72- return -1 ;
68+ if (bb_id >= imm.bb_id_to_index .size ())
69+ return -1 ;
70+ uint32_t idx = imm.bb_id_to_index [bb_id];
71+ return (idx == UINT32_MAX) ? -1 : static_cast <int >(idx);
7372}
7473
7574// ---------------------------------------------------------------------------
@@ -318,9 +317,8 @@ enter_basic_block(VmExecution& exec,
318317 const BBMetadata& target = imm.bb_metadata [static_cast <size_t >(bb_idx)];
319318
320319 // 2. Use pre-derived bb_enc_seed from BBMetadata (no stored_seed needed)
321- uint64_t enc_seed_u64 = 0 ;
322- std::memcpy (&enc_seed_u64, target.bb_enc_seed , 8 );
323- exec.enc_state = enc_seed_u64;
320+ // P6: pre-decoded at load time, avoids repeated memcpy
321+ exec.enc_state = target.bb_enc_seed_u64 ;
324322
325323 // 3. Reset instruction tracking
326324 exec.insn_index_in_bb = 0 ;
@@ -460,12 +458,8 @@ verify_bb_mac(const VmImmutable& imm,
460458 const uint32_t real_count = bb.insn_count_in_bb ;
461459 const uint32_t padded_count = imm.max_bb_insn_count ;
462460
463- // Derive bb_enc_seed for this BB
464- uint8_t enc_seed_bytes[8 ];
465- std::memcpy (enc_seed_bytes, bb.bb_enc_seed , 8 );
466-
467- uint64_t enc_state = 0 ;
468- std::memcpy (&enc_state, enc_seed_bytes, 8 );
461+ // P6: use pre-decoded enc_state (no memcpy needed)
462+ uint64_t enc_state = bb.bb_enc_seed_u64 ;
469463
470464 // Re-decrypt all instructions in this BB + dummy iterations for padding.
471465 //
@@ -479,8 +473,10 @@ verify_bb_mac(const VmImmutable& imm,
479473 auto insns = imm.blob .instructions ();
480474 const uint32_t total_insn_count = imm.blob .header ().insn_count ;
481475
482- // Stack buffer for MAC computation (only real instructions contribute)
483- std::vector<uint8_t > plaintext_bytes (real_count * 8 );
476+ // P1: stack-allocated scratch buffer (no heap allocation on hot path).
477+ // Sized to compile-time cap; blobs exceeding VM_MAX_BB_INSN_CAP are
478+ // rejected at load time.
479+ uint8_t plaintext_bytes[VM_MAX_BB_INSN_CAP * 8 ];
484480
485481 for (uint32_t j = 0 ; j < padded_count; ++j) {
486482 const bool is_real = (j < real_count);
@@ -496,7 +492,7 @@ verify_bb_mac(const VmImmutable& imm,
496492
497493 // Only write real plaintext to MAC buffer
498494 if (is_real)
499- std::memcpy (plaintext_bytes. data () + j * 8 , &plain, 8 );
495+ std::memcpy (plaintext_bytes + j * 8 , &plain, 8 );
500496
501497 // Always check REKEY (dummy iterations: sem_op won't match REKEY)
502498 VmInsn vinst{};
@@ -526,8 +522,8 @@ verify_bb_mac(const VmImmutable& imm,
526522 // MAC is computed over REAL instructions only (matches blob builder)
527523 uint8_t computed_mac[8 ];
528524 blake3_keyed_hash (imm.integrity_key ,
529- plaintext_bytes. data () ,
530- plaintext_bytes. size () ,
525+ plaintext_bytes,
526+ static_cast < size_t >(real_count) * 8 ,
531527 computed_mac, 8 );
532528
533529 // Compare with stored MAC (constant-time)
@@ -556,13 +552,8 @@ void replay_enc_state(VmExecution& exec, const VmEpoch& epoch,
556552
557553 const auto & bb = imm.bb_metadata [exec.current_bb_index ];
558554
559- // Derive bb_enc_seed from scratch (enter_basic_block already set enc_state,
560- // but we need the seed for the keystream replay).
561- uint8_t enc_seed_bytes[8 ];
562- std::memcpy (enc_seed_bytes, bb.bb_enc_seed , 8 );
563-
564- uint64_t es = 0 ;
565- std::memcpy (&es, enc_seed_bytes, 8 );
555+ // P6: use pre-decoded enc_seed (no memcpy needed)
556+ uint64_t es = bb.bb_enc_seed_u64 ;
566557
567558 // Replay SipHash chain: decrypt each instruction [0..target_insn_idx) and
568559 // advance enc_state, handling REKEY mutations along the way.
0 commit comments