Neha Gupta

85 papers A* 8A 1B 1C 3Misc 1Journal 51Unranked 20
YearRankTypeTitle / Venue / Authors
2026 J jnl
CoRR
Neha Gupta, Hamed Alimohammadi, Mohammad Shojafar, De Mi, Muhammad Nasir Mumtaz Bhutta
2026 J jnl
IEEE Open J. Commun. Soc.
Swathi Priya Indraganti, Suseela Vappangi, Anoop Kumar Mishra, Sudha Ellison Mathe, Ali Arshad Nasir, Thangavel Deepa, Neha Gupta
2026 J jnl
Eng. Appl. Artif. Intell.
Manu Singh, Neha Gupta, Shiva Tyagi, Ashima Rani, Vinod Kumar, Surbhi Sharma
2026 J jnl
Biomed. Signal Process. Control.
Dhyanendra Jain, Neha Gupta, Kamal Borana, Manish Kumar, Uma Tomer, Amit Kumar Pandey
2025 conf
KDD (2)
Hongying Zhao, Mert Bay, Zhenyu Zhao, Bradley C. Turnbull, Anbang Xu, Neha Gupta
2025 J jnl
J. Control. Decis.
Neha Gupta, Lillie Dewan
2025 conf
ISVLSI
Neha Gupta, Lomash Chandra Acharya, Mahipal Dargupally, Khoirom Johnson Singh, Amit Kumar Behera, Johan Euphrosine, Sudeb Dasgupta, Anand Bulusu
2025 J jnl
CoRR
Benjamin S. Allen, James L. Anchell, Victor Anisimov, Thomas Applencourt, Abhishek Bagusetty, Ramesh Balakrishnan, Riccardo Balin, Solomon Bekele, Colleen Bertoni, Cyrus Blackworth, Renzo Bustamante, Kevin Canada, John Carrier, Christopher Chan-nui, Lance C. Cheney, J. Taylor Childers, Paul K. Coffman, Susan Coghlan, Michael D'Mello, Murali Emani, Kyle Felker, Sam Foreman, Olivier Franza, Longfei Gao, Marta García, María Jesús Garzarán, Balazs Gerofi, Yasaman Ghadar, Neha Gupta, Kevin Harms, Väinö Hatanpää, Brian Holland, Carissa Holohan, Brian Homerding, Khalid Hossain, Louise Huot, Huda Ibeid, Joseph A. Insley, Sai Jayanthi, Hong Jiang, Wei Jiang, Xiao-Yong Jin, Jeongnim Kim, Christopher Knight, Kalyan Kumaran, JaeHyuk Kwack, Ti Leggett, Ben Lenard, Chris Lewis, Nevin Liber, Johann Lombardi, Raymond M. Loy, Ye Luo, Bethany Lusch, Nilakantan Mahadevan, Victor A. Mateevitsi, Gordon McPheeters, Ryan Milner, Vitali A. Morozov, Servesh Muralidharan, Tom Musta, Mrigendra Nagar, Vikram Narayana, Marieme Ngom, Anthony-Trung Nguyen, Nathan Nichols, Aditya Nishtala, James C. Osborn, Michael E. Papka, Scott Parker, Saumil Patel, Adrian C. Pope, Sucheta Raghunanda, Esteban Rangel, Paul M. Rich, Silvio Rizzi, Kris Rowe, Varuni Sastry, Adam Scovel, Filippo Simini, Haritha Siddabathuni Som, Patrick Steinbrecher, Rick Stevens, Xinmin Tian, Peter Upton, Thomas D. Uram, Archit Vasan, Álvaro Vázquez-Mayagoitia, Kaushik Velusamy, Brice Videau, Venkatram Vishwanath, Brian Whitney, Timothy J. Williams, Michael Woodacre, Sam Zeltner, Gengbin Zheng, Huihuo Zheng
2025 J jnl
Evol. Syst.
Neha Gupta, Suneet K. Gupta, Vanita Jain, Narpinder Singh, Jasjit S. Suri
2025 J jnl
CoRR
Kabir Khan, Priya Sharma, Arjun Mehta, Neha Gupta, Ravi Narayanan
2025 A* conf
ICLR
Harikrishna Narasimhan, Wittawat Jitkrittum, Ankit Singh Rawat, Seungyeon Kim, Neha Gupta, Aditya Krishna Menon, Sanjiv Kumar
2025 conf
SOCC
Mohammad Derawi, Marcos Xosé Alvarez Cid, Faouzi Alaya Cheikh, Neha Gupta, Nishu Gupta
2025 J jnl
Clust. Comput.
Umang Garg, Preeti Mishra, Neha Gupta, Emmanuel S. Pilli
2025 J jnl
CoRR
Neha Gupta, Aditya Maheshwari
2025 J jnl
CoRR
Mrinal Rawat, Ambuje Gupta, Rushil Goomer, Alessandro Di Bari, Neha Gupta, Roberto Pieraccini
2025 J jnl
IEEE Trans. Circuits Syst. II Express Briefs
Mahipal Dargupally, Lomash Chandra Acharya, Neha Gupta, Ahrron Kongala, Arvind K. Sharma, Sudeb Dasgupta, Anand Bulusu
2025 J jnl
Circuits Syst. Signal Process.
Vikas Maheshwari, Hemant Patidar, Neha Gupta, Rajib Kar
2025 J jnl
Soft Comput.
Yuvraj Sharma, Siddharth Gupta, Neha Gupta, Ekta Tiwari, Rajesh Singh, Narendra N. Khanna, Mustafa Al-Maini, Vijay S. Rathore, Puneet Ahluwalia, Vandana Kumari, D. Subbaram Naidu, Luca Saba, Jasjit S. Suri
2025 B conf
TrustCom
Neha Gupta, Liam O'Driscoll, Taneya Sharma, Mohammad Shojafar, Chuan Heng Foh, Ioana Boureanu, Helen Treharne, Sotiris Moschoyiannis
2025 J jnl
CoRR
Mrinal Rawat, Arkajyoti Chakraborty, Neha Gupta, Roberto Pieraccini
2024 A* conf
KDD
Shadow Zhao, Mert Bay, Anbang Xu, Neha Gupta
2024 J jnl
CoRR
Harikrishna Narasimhan, Wittawat Jitkrittum, Ankit Singh Rawat, Seungyeon Kim, Neha Gupta, Aditya Krishna Menon, Sanjiv Kumar
2024 J jnl
Comput. Biol. Medicine
Soham Bhattacharya, Adrish Dutta, Pijush Kanti Khanra, Neha Gupta, Ritesh Dutta, Nikolay T. Tzvetkov, Luigi Milella, Maria Ponticelli
2024 A* conf
ICLR
Neha Gupta, Harikrishna Narasimhan, Wittawat Jitkrittum, Ankit Singh Rawat, Aditya Krishna Menon, Sanjiv Kumar
2024 J jnl
CoRR
Neha Gupta, Harikrishna Narasimhan, Wittawat Jitkrittum, Ankit Singh Rawat, Aditya Krishna Menon, Sanjiv Kumar
2024 A* conf
ICLR
Harikrishna Narasimhan, Aditya Krishna Menon, Wittawat Jitkrittum, Neha Gupta, Sanjiv Kumar
2024 J jnl
IEEE Trans. Comput. Aided Des. Integr. Circuits Syst.
Lomash Chandra Acharya, Arvind K. Sharma, Neeraj Mishra, Khoirom Johnson Singh, Mahipal Dargupally, Neha Gupta, Nayakanti Sai Shabarish, Ajoy Mandal, Venkatraman Ramakrishnan, Sudeb Dasgupta, Anand Bulusu
2024 conf
APCCAS
Sambhav Sharma, Garima Choudhary, Neha Gupta, Sunil Rathore, Anand Bulusu, Sudeb Dasgupta
2023 A* conf
KDD
Hongying Zhao, Zhenyu Zhao, Anbang Xu, Neha Gupta, Mert Bay
2023 J jnl
SN Comput. Sci.
Neha Gupta, Vinita Jindal, Punam Bedi
2023 conf
APCCAS
Ravi, Lomash Chandra Acharya, Mahipal Dargupally, Neha Gupta, Neeraj Mishra, Lalit Mohan Dani, Nilotpal Sarma, Devesh Dwivedi, Sudeb Dasgupta, Anand Bulusu
2023 conf
ICC Workshops
Neha Gupta, Mohammad Shojafar, Chuan Heng Foh, Rahim Tafazolli
2023 conf
APCCAS
Mahipal Dargupally, Lomash Chandra Acharya, Khoirom Johnson Singh, Neha Gupta, Arvind K. Sharma, Sudeb Dasgupta, Anand Bulusu
2023 Misc conf
VLSID
Dinesh Kushwaha, Ashish Joshi, Neha Gupta, Aditya Sharma, Sandeep Miryala, Rajiv V. Joshi, Sudeb Dasgupta, Anand Bulusu
2023 conf
SMACD
Lomash Chandra Acharya, Anubhav Kumar, Khoirom Johnson Singh, Neha Gupta, Nayakanti Sai Shabarish, Neeraj Mishra, Mahipal Dargupally, Arvind Kumar Sharma, Venkatraman Ramakrishnan, Ajoy Mandal, Sudeb Dasgupta, Anand Bulusu
2023 J jnl
Comput. Biol. Medicine
Sanjay Saxena, Biswajit Jena, Bibhabasu Mohapatra, Neha Gupta, Manudeep S. Kalra, Mario Scartozzi, Luca Saba, Jasjit S. Suri
2023 J jnl
Discov. Artif. Intell.
Sushil Kalyani, Neha Gupta
2023 J jnl
Microelectron. J.
Syed Farah Naz, Ambika Prasad Shah, Neha Gupta
2023 J jnl
J. Control. Decis.
Neha Gupta, Lillie Dewan
2023 J jnl
J. Oper. Res. Soc.
Neha Gupta, Seung Hyun Lee
2023 A* conf
NeurIPS
Wittawat Jitkrittum, Neha Gupta, Aditya Krishna Menon, Harikrishna Narasimhan, Ankit Singh Rawat, Sanjiv Kumar
2023 J jnl
CoRR
Wittawat Jitkrittum, Neha Gupta, Aditya Krishna Menon, Harikrishna Narasimhan, Ankit Singh Rawat, Sanjiv Kumar
2022 A* conf
KDD
Neha Gupta, Zhenyu Zhao, Mert Bay, Anbang Xu, Faisal Farooq
2022 C conf
ISCAS
Dinesh Kushwaha, Aditya Sharma, Neha Gupta, Ritik Raj, Ashish Joshi, Jwalant Mishra, Rajat Kohli, Sandeep Miryala, Rajiv V. Joshi, Sudeb Dasgupta, Anand Bulusu
2022 conf
ICECS 2022
Neha Gupta, Ashish Joshi, Dinesh Kushwaha, Vinod Menezes, Rashmi Sachan, Sudeb Dasgupta, Anand Bulusu
2022 J jnl
IEEE Trans. Circuits Syst. II Express Briefs
Dinesh Kushwaha, Ashish Joshi, Chaudhry Indra Kumar, Neha Gupta, Sandeep Miryala, Rajiv V. Joshi, Sudeb Dasgupta, Anand Bulusu
2022 J jnl
Concurr. Comput. Pract. Exp.
Neha Gupta, Rajendra Prasad Mahapatra
2022 J jnl
Comput. Secur.
Neha Gupta, Vinita Jindal, Punam Bedi
2022 J jnl
Neurocomputing
Gopal Raut, Anton Biasizzo, Narendra Singh Dhakad, Neha Gupta, Gregor Papa, Santosh Kumar Vishvakarma
2022 J jnl
Trans. Mach. Learn. Res.
Neha Gupta, Jamie Smith, Ben Adlam, Zelda E. Mariet
2022 J jnl
CoRR
Neha Gupta, Jamie Smith, Ben Adlam, Zelda Mariet
2022 J jnl
Ann. GIS
Neha Gupta, Sanjit Kumar Pal, Josodhir Das
2022 J jnl
Artif. Intell. Rev.
Neha Gupta, Suneet K. Gupta, Rajesh K. Pathak, Vanita Jain, Parisa Rashidi, Jasjit S. Suri
2022 J jnl
Mechatron. Syst. Control.
Neha Gupta, Lillie Dewan
2022 J jnl
CoRR
Ben Adlam, Neha Gupta, Zelda Mariet, Jamie Smith
2021 J jnl
Appl. Intell.
Punam Bedi, Neha Gupta, Vinita Jindal
2021 J jnl
Comput. Networks
Neha Gupta, Vinita Jindal, Punam Bedi
2021 J jnl
Int. J. Bioinform. Res. Appl.
Gaurav Gupta, Neha Gupta, Ankit Gupta, Pankaj Vaidya, Girish Kumar Singh, Varun Jaiswal
2021 J jnl
SN Comput. Sci.
Punam Bedi, Shivani Dhiman, Pushkar Gole, Neha Gupta, Vinita Jindal
2021 J jnl
Symmetry
Neha Gupta, Kamali Gupta, Shalli Rani, Deepika Koundal, Atef Zaguia
2021 conf
IC3
Gautham Sathish Nambissan, Prateek Mahajan, Shivam Sharma, Neha Gupta
2021 conf
ACM Great Lakes Symposium on VLSI
Neha Gupta, Nikhil Agrawal, Narendra Singh Dhakad, Ambika Prasad Shah, Santosh Kumar Vishvakarma, Patrick Girard
2020 J jnl
IEEE Signal Process. Lett.
Ekant Sharma, Neha Gupta, Sauradeep Dey, Rohit Budhiraja
2020 J jnl
CoRR
Punam Bedi, Neha Gupta, Vinita Jindal
2020 J jnl
CoRR
Vaggos Chatziafratis, Neha Gupta, Euiwoong Lee
2020 J jnl
CoRR
Punam Bedi, Shivani, Pushkar Gole, Neha Gupta, Vinita Jindal
2020 J jnl
Entropy
Neha Gupta, Arun Kumar, Nikolai Leonenko
2019 conf
VDAT
Neha Gupta, Jitesh Prasad, Rana Sagar Kumar, Gunjan Rajput, Santosh Kumar Vishvakarma
2019 conf
VDAT
Sajid Khan, Neha Gupta, Gopal Raut, Gunjan Rajput, Jai Gopal Pandey, Santosh Kumar Vishvakarma
2019 J jnl
Microelectron. J.
Prachi Sanvale, Neha Gupta, Vaibhav Neema, Ambika Prasad Shah, Santosh Kumar Vishvakarma
2019 J jnl
Microelectron. J.
Sajid Khan, Ambika Prasad Shah, Neha Gupta, Shailesh Singh Chouhan, Jai Gopal Pandey, Santosh Kumar Vishvakarma
2019 conf
VDAT
Sajid Khan, Neha Gupta, Abhinav Vishwakarma, Shailesh Singh Chouhan, Jai Gopal Pandey, Santosh Kumar Vishvakarma
2019 conf
MLDM (2)
Neha Gupta, Purushothaman Ethiraj
2019 conf
VDAT
Neha Gupta, Tanisha Gupta, Sajid Khan, Abhinav Vishwakarma, Santosh Kumar Vishvakarma
2019 conf
SPAWC
Neha Gupta, Ekant Sharma, Sauradeep Dey, Rohit Budhiraja
2018 conf
ICACCI
Neha Gupta, Punam Bedi
2018 A* conf
CHI
Martin Flintham, Christian Karner, Khaled Bachour, Helen Creswick, Neha Gupta, Stuart Moran
2017 J jnl
Proc. ACM Interact. Mob. Wearable Ubiquitous Technol.
Ujwal Gadiraju, Alessandro Checco, Neha Gupta, Gianluca Demartini
2016 A conf
ASSETS
Thomas Hahn, Hidayat Ur Rahman, Richard S. Segall, Christoph Heim, Raphaela Brunson, Ankush Sharma, Maryam Aslam, Ana Lara-Rodriguez, Md. Sahidul Islam, Neha Gupta, Charles S. Embry, Patrick Grossmann, Shahrukh Babar, Gregory A. Skibinski, Fusheng Tang
2015 conf
Crowdsourcing and Human-Centered Experiments
David Martin, Sheelagh Carpendale, Neha Gupta, Tobias Hoßfeld, Babak Naderi, Judith Redi, Ernestasia Siahaan, Ina Wechsung
2014 C conf
SIN
Smita Naval, Vijay Laxmi, Neha Gupta, Manoj Singh Gaur, Muttukrishnan Rajarajan
2014 C conf
PST
Neha Gupta, Smita Naval, Vijay Laxmi, Manoj Singh Gaur, Muttukrishnan Rajarajan
2013 conf
WOCN
Neha Gupta, Rajeev Kumar Singh, Manish Shrivastava
2012 J jnl
CoRR
Neha Gupta, Sapna Singh, Meenakshi Suthar, Priyanka Soni
2005 J jnl
Pattern Recognit.
Monu Agrawal, Neha Gupta, R. Shreelekshmi, M. Narasimha Murty
redb/extractors/decompiler/bninja/analysis/cfg_features.py
← Index redb/extractors/decompiler/bninja/analysis/cfg_features.py python
import struct
from collections import deque
from typing import Optional

import blake3
import mmh3


# ---------------------------------------------------------------------------
# Task 1.1: Core Graph Utilities
# ---------------------------------------------------------------------------

def bfs_order(successors: list[list[int]], n: int) -> list[int]:
    """
    BFS traversal from node 0 (entry block), returns node indices in visit order.
    Unreachable nodes appended at the end.
    """
    if n == 0:
        return []

    visited = set()
    order = []
    queue = deque([0])
    visited.add(0)

    while queue:
        idx = queue.popleft()
        order.append(idx)
        for target in successors[idx]:
            if target not in visited:
                visited.add(target)
                queue.append(target)

    # Append unreachable blocks (dead code)
    for i in range(n):
        if i not in visited:
            order.append(i)

    return order


def bfs_max_depth(successors: list[list[int]], n: int) -> int:
    """
    Maximum BFS depth from entry block (node 0).
    Replaces the per-block depth column with a single scalar.
    """
    if n == 0:
        return 0

    depth = {0: 0}
    max_d = 0
    queue = deque([0])

    while queue:
        node = queue.popleft()
        for s in successors[node]:
            if s not in depth:
                depth[s] = depth[node] + 1
                if depth[s] > max_d:
                    max_d = depth[s]
                queue.append(s)

    return max_d


# ---------------------------------------------------------------------------
# Task 1.2: Back-Edge Detection (Iterative DFS)
# ---------------------------------------------------------------------------

def count_back_edges(successors: list[list[int]], n: int) -> int:
    """
    Count natural loops via iterative DFS back-edge detection.
    A back edge is an edge to a GRAY (in-stack) node.

    Iterative to avoid stack overflow on functions with 1000+ blocks
    (common in obfuscated malware, VM dispatchers, unrolled loops).
    """
    if n == 0:
        return 0

    WHITE, GRAY, BLACK = 0, 1, 2
    color = [WHITE] * n
    back_edges = 0

    stack = [(0, iter(successors[0]))]
    color[0] = GRAY

    while stack:
        u, children = stack[-1]
        try:
            v = next(children)
            if color[v] == GRAY:
                back_edges += 1
            elif color[v] == WHITE:
                color[v] = GRAY
                stack.append((v, iter(successors[v])))
        except StopIteration:
            color[u] = BLACK
            stack.pop()

    return back_edges


# ---------------------------------------------------------------------------
# Task 1.3: Topology Hash
# ---------------------------------------------------------------------------

def compute_topology_hash(
    successors: list[list[int]],
    bfs: list[int],
    n: int,
) -> bytes:
    """
    BLAKE3 hash of BFS-ordered canonical adjacency.
    Pure graph shape — ignores all block content.
    Two functions with identical control flow structure produce identical hashes.

    Returns 16 bytes (128-bit).
    """
    if n == 0:
        return b'\x00' * 16

    # Remap: original index -> BFS position
    remap = {original: position for position, original in enumerate(bfs)}

    canonical = bytearray()
    for position in range(n):
        original_idx = bfs[position]
        remapped_succs = sorted(
            remap[s] for s in successors[original_idx] if s in remap
        )
        # Pack: node_index (2 bytes) + num_successors (1 byte) + successor indices (2 bytes each)
        canonical.extend(struct.pack('<HB', position, len(remapped_succs)))
        for s in remapped_succs:
            canonical.extend(struct.pack('<H', s))

    return blake3.blake3(bytes(canonical)).digest(length=16)


# ---------------------------------------------------------------------------
# Task 1.4: MD-Index (Top-Down and Bottom-Up)
# ---------------------------------------------------------------------------

def compute_md_index_topdown(
    successors: list[list[int]],
    predecessors: list[list[int]],
    bfs: list[int],
) -> int:
    """
    BinDiff-style top-down MD-index.
    Hash of (in_degree, out_degree) sequence in BFS order from entry.
    Returns UInt64.
    """
    if not bfs:
        return 0

    degree_bytes = bytearray()
    for idx in bfs:
        in_deg = min(len(predecessors[idx]), 255)
        out_deg = min(len(successors[idx]), 255)
        degree_bytes.extend(struct.pack('<BB', in_deg, out_deg))

    h = blake3.blake3(bytes(degree_bytes)).digest(length=8)
    return struct.unpack('<Q', h)[0]


def compute_md_index_bottomup(
    successors: list[list[int]],
    predecessors: list[list[int]],
    n: int,
) -> int:
    """
    Bottom-up MD-index: BFS from exit blocks (no successors),
    traversing edges in reverse.
    Returns UInt64.
    """
    if n == 0:
        return 0

    exits = [i for i in range(n) if len(successors[i]) == 0]
    if not exits:
        exits = [n - 1]  # Fallback: use last block

    visited = set(exits)
    order = []
    queue = deque(exits)

    while queue:
        idx = queue.popleft()
        order.append(idx)
        for pred in predecessors[idx]:
            if pred not in visited:
                visited.add(pred)
                queue.append(pred)

    # Append unreachable blocks
    for i in range(n):
        if i not in visited:
            order.append(i)

    degree_bytes = bytearray()
    for idx in order:
        in_deg = min(len(predecessors[idx]), 255)
        out_deg = min(len(successors[idx]), 255)
        degree_bytes.extend(struct.pack('<BB', in_deg, out_deg))

    h = blake3.blake3(bytes(degree_bytes)).digest(length=8)
    return struct.unpack('<Q', h)[0]


# ---------------------------------------------------------------------------
# Task 1.5: Prime Product
# ---------------------------------------------------------------------------

# Small primes assigned to LLIL opcode categories.
# Keys are the integer values of binaryninja.LowLevelILOperation enum members.
# We use integer keys so this module doesn't import binaryninja.
#
# Mapping rationale: same operation class -> same prime.
# Using LLIL (not native asm) makes this architecture-independent.
#
# Populated at import time by cfg.py using the real LowLevelILOperation enum values.
# Unknown ops map to prime 1 (identity element) in compute_prime_product().
LLIL_OP_PRIMES: dict[int, int] = {}


def compute_prime_product(llil_operations: list[int]) -> int:
    """
    Product of small primes assigned to each LLIL opcode.
    Position-independent: block reordering doesn't change the result.
    Mod 2^64 for fixed-size storage.

    Args:
        llil_operations: flat list of LLIL operation enum integer values
                         for all instructions in the function.
    Returns:
        UInt64 prime product, or 0 if no instructions.
    """
    if not llil_operations:
        return 0

    product = 1
    for op in llil_operations:
        prime = LLIL_OP_PRIMES.get(op, 1)
        product = (product * prime) % (2**64)

    return product


# ---------------------------------------------------------------------------
# Task 1.6: ACFG Block Features
# ---------------------------------------------------------------------------

# Instruction category indices for ACFG feature vectors
CAT_ARITHMETIC = 0
CAT_LOGIC = 1
CAT_TRANSFER = 2
CAT_CALL = 3
CAT_COMPARISON = 4
CAT_MEMORY = 5
CAT_OTHER = 6

# Maps LLIL operation integer values to category indices.
# Populated at import time by cfg.py using the real LowLevelILOperation enum.
LLIL_OP_CATEGORIES: dict[int, int] = {}


def build_block_features(
    block_llil_ops: list[list[int]],
    successors: list[list[int]],
    n: int,
) -> list[list[int]]:
    """
    Extract Gemini-style ACFG features per block.

    Args:
        block_llil_ops: per-block list of LLIL operation integer values.
                        block_llil_ops[i] is the list of ops for block i.
                        Empty list if LLIL unavailable for that block.
        successors: index-based adjacency list.
        n: number of blocks.

    Returns:
        List of [instr_count, arithmetic, logic, transfer, call, comparison,
                 memory, successor_count] per block. All values capped at 65535.
    """
    features = []
    for i in range(n):
        cats = [0, 0, 0, 0, 0, 0, 0]
        ops = block_llil_ops[i] if i < len(block_llil_ops) else []
        for op in ops:
            cat = LLIL_OP_CATEGORIES.get(op, CAT_OTHER)
            cats[cat] += 1

        instr_count = len(ops)
        features.append([
            min(instr_count, 65535),
            min(cats[CAT_ARITHMETIC], 65535),
            min(cats[CAT_LOGIC], 65535),
            min(cats[CAT_TRANSFER], 65535),
            min(cats[CAT_CALL], 65535),
            min(cats[CAT_COMPARISON], 65535),
            min(cats[CAT_MEMORY], 65535),
            min(len(successors[i]), 65535),
        ])

    return features


# ---------------------------------------------------------------------------
# Task 1.7: CFG Feature TLSH
# ---------------------------------------------------------------------------

def compute_cfg_feature_tlsh(
    bb_features: list[list[int]],
    bfs: list[int],
) -> Optional[str]:
    """
    TLSH hash of BFS-ordered per-block feature vectors.
    Captures both structure (BFS ordering) and instruction distribution.

    Returns TLSH hex string or None if too few bytes for TLSH (< 50).
    """
    import tlsh as _tlsh

    feature_bytes = bytearray()
    for idx in bfs:
        feats = bb_features[idx]
        feature_bytes.extend(struct.pack(
            '<HBBBBBBB',
            min(feats[0], 65535),
            min(feats[1], 255),
            min(feats[2], 255),
            min(feats[3], 255),
            min(feats[4], 255),
            min(feats[5], 255),
            min(feats[6], 255),
            min(feats[7], 255),
        ))

    if len(feature_bytes) < 50:
        return None

    try:
        h = _tlsh.hash(bytes(feature_bytes))
        return h if h and h != 'TNULL' else None
    except Exception:
        return None


# ---------------------------------------------------------------------------
# Task 1.8: WL-MinHash
# ---------------------------------------------------------------------------

# Pre-computed seeds for MinHash permutations.
NUM_WL_MINHASH_PERMS = 128
_WL_MINHASH_SEEDS = list(range(NUM_WL_MINHASH_PERMS))  # Seeds 0..127


def compute_wl_minhash(
    successors: list[list[int]],
    predecessors: list[list[int]],
    bb_features: list[list[int]],
    n: int,
    iterations: int = 3,
) -> list[int]:
    """
    Weisfeiler-Leman MinHash for fuzzy topology similarity.

    Initial labels: mmh3 hash of per-block ACFG feature tuple (content-aware).
    WL refinement: incorporate sorted neighbor labels at each iteration.
    MinHash: 128-permutation signature over shingle set.

    Returns list of 128 uint8 values, or [255]*128 sentinel for empty functions.
    """
    if n == 0:
        return [255] * NUM_WL_MINHASH_PERMS

    # Initial labels: hash of instruction category tuple per block
    labels = []
    for i in range(n):
        feats = bb_features[i] if i < len(bb_features) else [0] * 8
        # mmh3 with seed=0 for initial labels
        label = mmh3.hash(str(tuple(feats)), 0) & 0xFFFFFFFF
        labels.append(label)

    # Collect shingles: (iteration, label) pairs as strings for mmh3
    shingles: set[str] = set()

    # Iteration 0: individual block labels
    for label in labels:
        shingles.add(f"0:{label}")

    # WL iterations: refine labels by neighborhood aggregation
    for iteration in range(1, iterations + 1):
        new_labels = []
        for i in range(n):
            succ_labels = tuple(sorted(labels[s] for s in successors[i]))
            pred_labels = tuple(sorted(labels[p] for p in predecessors[i]))
            composite = f"{labels[i]}|{succ_labels}|{pred_labels}"
            new_label = mmh3.hash(composite, 0) & 0xFFFFFFFF
            new_labels.append(new_label)
            shingles.add(f"{iteration}:{new_label}")
        labels = new_labels

    if not shingles:
        return [255] * NUM_WL_MINHASH_PERMS

    # Compute MinHash signature using mmh3 with different seeds
    shingle_list = list(shingles)
    signature = []
    for seed in _WL_MINHASH_SEEDS:
        min_val = 0xFFFFFFFF
        for s in shingle_list:
            h = mmh3.hash(s, seed) & 0xFFFFFFFF
            if h < min_val:
                min_val = h
        # Compress to uint8 for storage
        signature.append(min_val & 0xFF)

    return signature


# ---------------------------------------------------------------------------
# Task 1.9: Packed Adjacency
# ---------------------------------------------------------------------------

def pack_adjacency(successors: list[list[int]]) -> list[int]:
    """
    Pack CFG edges as Array(UInt32).
    Each UInt32 = (source_index << 16) | target_index.
    Supports up to 65,535 blocks per function.
    """
    edges = []
    for src, targets in enumerate(successors):
        for tgt in targets:
            if src < 65536 and tgt < 65536:
                edges.append((src << 16) | tgt)
    return edges