Vaughn Betz

155 papers A 28B 30Misc 9Journal 54Unranked 32
YearRankTypeTitle / Venue / Authors
2025 J jnl
ACM Trans. Reconfigurable Technol. Syst.
Mohamed A. Elgammal, Amin Mohaghegh, Soheil Gholami Shahrouz, Fatemehsadat Mahmoudi, Fahrican Kosar, Kimia Talaei, Joshua Fife, Daniel Khadivi, Kevin E. Murray, Andrew Boutros, Kenneth B. Kent, Jeffrey B. Goeders, Vaughn Betz
2025 B conf
FPL
Junius Pun, Xilai Dai, Grace Zgheib, Mahesh A. Iyer, Andrew Boutros, Vaughn Betz, Mohamed S. Abdelfattah
2025 J jnl
CoRR
Junius Pun, Xilai Dai, Grace Zgheib, Mahesh A. Iyer, Andrew Boutros, Vaughn Betz, Mohamed S. Abdelfattah
2025 J jnl
ACM Trans. Reconfigurable Technol. Syst.
Vaughn Betz
2025 J jnl
Proc. IEEE
Andrew Boutros, Aman Arora, Vaughn Betz
2025 B conf
FPL
Mohamed A. Elgammal, Vaughn Betz
2025 J jnl
ACM Trans. Reconfigurable Technol. Syst.
Mohamed A. Elgammal, Amin Mohaghegh, Soheil Gholami Shahrouz, Fatemehsadat Mahmoudi, Fahrican Kosar, Kimia Talaei, Joshua Fife, Daniel Khadivi, Kevin E. Murray, Andrew Boutros, Kenneth B. Kent, Jeffrey B. Goeders, Vaughn Betz
2024 B conf
FPL
Taikun Zhang, Andrew Boutros, Sergey Gribok, Kwadwo Boateng, Vaughn Betz
2024 B conf
FPL
Rachel Selina Rajarathnam, Kate Thurmer, Vaughn Betz, Mahesh A. Iyer, David Z. Pan
2024 J jnl
CoRR
Andrew Boutros, Aman Arora, Vaughn Betz
2024 B conf
FPL
Mario Doumet, Marius Stan, Mathew Hall, Vaughn Betz
2024 J jnl
CoRR
Mario Doumet, Marius Stan, Mathew Hall, Vaughn Betz
2024 J jnl
ACM Trans. Reconfigurable Technol. Syst.
Anupreetham Anupreetham, Mohamed Ibrahim, Mathew Hall, Andrew Boutros, Ajay Kuzhively, Abinash Mohanty, Eriko Nurvitadhi, Vaughn Betz, Yu Cao, Jae-sun Seo
2024 conf
ICFPT
Alexandre Singer, Hang Yan, Guozheng Zhang, Mark C. Jeffrey, Mirjana Stojilovic, Vaughn Betz
2024 conf
ICFPT
Fahrican Kosar, Mirjana Stojilovic, Vaughn Betz
2024 Misc conf
FCCM
Taikun Zhang, Andrew Boutros, Sergey Gribok, Kwadwo Boateng, Vaughn Betz
2024 B conf
FPL
Soheil Gholami Shahrouz, Vaughn Betz
2024 conf
HEART
Kate Thurmer, Vaughn Betz
2023 B conf
FPL
Andrew Boutros, Stephen More, Vaughn Betz
2023 conf
HEART
Mohamed A. Elgammal, Vaughn Betz
2023 conf
ICFPT
Mohamed Ibrahim, Zhipeng Zhao, Mathew Hall, Vaughn Betz
2023 conf
ICFPT
Andrew Boutros, Fatemehsadat Mahmoudi, Amin Mohaghegh, Stephen More, Vaughn Betz
2023 J jnl
IEEE Trans. Comput. Aided Des. Integr. Circuits Syst.
Aman Arora, Andrew Boutros, Seyed Alireza Damghani, Karan Mathur, Vedant Mohanty, Tanmay Anand, Mohamed A. Elgammal, Kenneth B. Kent, Vaughn Betz, Lizy K. John
2023 A conf
FPGA
Dana How, Tim Ansell, Vaughn Betz, Chris Lavin, Ted Speers, Pierre-Emmanuel Gaillardon
2023 Misc conf
FCCM
Srivatsan Srinivasan, Andrew Boutros, Fatemehsadat Mahmoudi, Vaughn Betz
2023 J jnl
CoRR
Andrew Boutros, Eriko Nurvitadhi, Vaughn Betz
2023 conf
ICFPT
Fatemehsadat Mahmoudi, Mohamed A. Elgammal, Soheil Gholami Shahrouz, Kevin E. Murray, Vaughn Betz
2023 B conf
FPL
Amin Mohaghegh, Vaughn Betz
2023 B conf
FPL
Kimia Talaei Khoozani, Arash Ahmadian Dehkordi, Vaughn Betz
2023 J jnl
ACM Trans. Reconfigurable Technol. Syst.
Sameh Attia, Vaughn Betz
2023 B conf
FPL
Ruichen Chen, Shengyao Lu, Mohamed A. Elgammal, Peter Chun, Vaughn Betz, Di Niu
2023 conf
HEART
Mohamed A. Elgammal, Omar Mohamed Awad, Isak Edo Vivancos, Andreas Moshovos, Vaughn Betz
2022 J jnl
IEEE Access
Andrew Boutros, Eriko Nurvitadhi, Vaughn Betz
2022 conf
FPT
Marius Stan, Mathew Hall, Mohamed Ibrahim, Vaughn Betz
2022 conf
FPT
Mohamed A. Elgammal, Vaughn Betz
2022 B conf
FPL
Andrew Boutros, Eriko Nurvitadhi, Vaughn Betz
2022 J jnl
IEEE Trans. Comput. Aided Des. Integr. Circuits Syst.
Mohamed A. Elgammal, Kevin E. Murray, Vaughn Betz
2022 J jnl
IEEE Trans. Computers
Sameh Attia, Vaughn Betz
2022 J jnl
ACM Trans. Reconfigurable Technol. Syst.
Aman Arora, Moinak Ghosh, Samidh Mehta, Vaughn Betz, Lizy K. John
2021 B conf
FPL
Anupreetham Anupreetham, Mohamed Ibrahim, Mathew Hall, Andrew Boutros, Ajay Kuzhively, Abinash Mohanty, Eriko Nurvitadhi, Vaughn Betz, Yu Cao, Jae-sun Seo
2021 B conf
FPL
Aman Arora, Andrew Boutros, Daniel Rauch, Aishwarya Rajen, Aatman Borda, Seyed Alireza Damghani, Samidh Mehta, Sangram Kate, Pragnesh Patel, Kenneth B. Kent, Vaughn Betz, Lizy K. John
2021 J jnl
CoRR
Aman Arora, Andrew Boutros, Daniel Rauch, Aishwarya Rajen, Aatman Borda, Seyed Alireza Damghani, Samidh Mehta, Sangram Kate, Pragnesh Patel, Kenneth B. Kent, Vaughn Betz, Lizy K. John
2021 J jnl
IEEE Trans. Biomed. Eng.
Abdul-Amir Yassine, Lothar Lilge, Vaughn Betz
2021 conf
ICM
Andrew Boutros, Eriko Nurvitadhi, Vaughn Betz
2021 conf
FPT
Sameh Attia, Vaughn Betz
2021 A conf
FPGA
Aman Arora, Samidh Mehta, Vaughn Betz, Lizy K. John
2020 conf
ASP-DAC
Kevin E. Murray, Sheng Zhong, Vaughn Betz
2020 conf
FPT
Andrew Boutros, Eriko Nurvitadhi, Rui Ma, Sergey Gribok, Zhipeng Zhao, James C. Hoe, Vaughn Betz, Martin Langhammer
2020 J jnl
ACM Trans. Reconfigurable Technol. Syst.
Mohamed Eldafrawy, Andrew Boutros, Sadegh Yazdanshenas, Vaughn Betz
2020 J jnl
ACM Trans. Reconfigurable Technol. Syst.
Sameh Attia, Vaughn Betz
2020 conf
FPT
Mathew Hall, Vaughn Betz
2020 A conf
FPGA
Mathew Hall, Vaughn Betz
2020 J jnl
CoRR
Mathew Hall, Vaughn Betz
2020 conf
FPT
Mohamed A. Elgammal, Kevin E. Murray, Vaughn Betz
2020 conf
FPT
Andrew Boutros, Mathew Hall, Nicolas Papernot, Vaughn Betz
2020 J jnl
CoRR
Andrew Boutros, Mathew Hall, Nicolas Papernot, Vaughn Betz
2020 J jnl
IEEE Trans. Very Large Scale Integr. Syst.
Kevin E. Murray, Jason Luu, Matthew J. P. Walker, Conor McCullough, Sen Wang, Safeen Huda, Bo Yan, Charles Chiasson, Kenneth B. Kent, Jason Helge Anderson, Jonathan Rose, Vaughn Betz
2020 J jnl
IEEE Trans. Very Large Scale Integr. Syst.
Ibrahim Ahmed, Linda L. Shen, Vaughn Betz
2020 A conf
FPGA
Sameh Attia, Vaughn Betz
2020 conf
FPT
Sameh Attia, Vaughn Betz
2020 J jnl
IEEE Micro
Kevin E. Murray, Mohamed A. Elgammal, Vaughn Betz, Tim Ansell, Keith Rothman, Alessandro Comodi
2020 A conf
FPGA
Tanner Young-Schultz, Lothar Lilge, Stephen Brown, Vaughn Betz
2020 J jnl
ACM Trans. Reconfigurable Technol. Syst.
Kevin E. Murray, Oleg Petelin, Sheng Zhong, Jia Min Wang, Mohamed Eldafrawy, Jean-Philippe Legault, Eugene Sha, Aaron Graham, Jean Wu, Matthew J. P. Walker, Hanqing Zeng, Panagiotis Patros, Jason Luu, Kenneth B. Kent, Vaughn Betz
2019 B conf
FPL
Ibrahim Ahmed, Linda L. Shen, Vaughn Betz
2019 J jnl
ACM Trans. Reconfigurable Technol. Syst.
Sadegh Yazdanshenas, Vaughn Betz
2019 J jnl
IEEE Trans. Comput. Aided Des. Integr. Circuits Syst.
Kevin E. Murray, Andrea Suardi, Vaughn Betz, George A. Constantinides
2019 J jnl
ACM Trans. Reconfigurable Technol. Syst.
Ibrahim Ahmed, Shuze Zhao, James Meijers, Olivier Trescases, Vaughn Betz
2019 Misc conf
FCCM
Linda L. Shen, Ibrahim Ahmed, Vaughn Betz
2019 A conf
FPGA
Andrew Boutros, Mohamed Eldafrawy, Sadegh Yazdanshenas, Vaughn Betz
2019 Misc conf
FCCM
Sameh Attia, Vaughn Betz
2019 J jnl
IEEE Trans. Very Large Scale Integr. Syst.
Sadegh Yazdanshenas, Vaughn Betz
2018 Misc conf
FCCM
Abdul-Amir Yassine, Yasmin Afsharnejad, Omar Ragheb, Vaughn Betz, Paul Chow
2018 J jnl
IEEE Trans. Comput. Aided Des. Integr. Circuits Syst.
Ibrahim Ahmed, Shuze Zhao, Olivier Trescases, Vaughn Betz
2018 B conf
FPL
Ibrahim Ahmed, Shuze Zhao, James Meijers, Olivier Trescases, Vaughn Betz
2018 B conf
FPL
Andrew Boutros, Sadegh Yazdanshenas, Vaughn Betz
2018 J jnl
ACM Trans. Reconfigurable Technol. Syst.
Kosuke Tatsumura, Sadegh Yazdanshenas, Vaughn Betz
2018 J jnl
IEEE Trans. Ind. Electron.
Shuze Zhao, Ibrahim Ahmed, Vaughn Betz, Ashraf Lotfi, Olivier Trescases
2018 conf
HEART
Yasmin Afsharnejad, Abdul-Amir Yassine, Omar Ragheb, Paul Chow, Vaughn Betz
2018 J jnl
ACM Trans. Reconfigurable Technol. Syst.
Henry Wong, Vaughn Betz, Jonathan Rose
2018 conf
FPT
Sadegh Yazdanshenas, Vaughn Betz
2018 J jnl
IEEE Access
Sadegh Yazdanshenas, Vaughn Betz
2018 B conf
FPL
Mustafa Abbas, Vaughn Betz
2018 conf
FPT
Kevin E. Murray, Vaughn Betz
2018 J jnl
ACM Trans. Reconfigurable Technol. Syst.
Oleg Petelin, Vaughn Betz
2018 J jnl
ACM Trans. Reconfigurable Technol. Syst.
Andrew Boutros, Sadegh Yazdanshenas, Vaughn Betz
2017 conf
FPT
Sadegh Yazdanshenas, Vaughn Betz
2017 J jnl
IEEE Trans. Computers
Mohamed S. Abdelfattah, Andrew Bitar, Vaughn Betz
2017 A conf
FPGA
Sadegh Yazdanshenas, Kosuke Tatsumura, Vaughn Betz
2017 B conf
FPL
Ibrahim Ahmed, Shuze Zhao, Olivier Trescases, Vaughn Betz
2017 B conf
FPL
Sadegh Yazdanshenas, Vaughn Betz
2017 A conf
DATE
Kevin E. Murray, Andrea Suardi, Vaughn Betz, George A. Constantinides
2016 Misc conf
FCCM
Henry Wong, Vaughn Betz, Jonathan Rose
2016 conf
FPT
Kosuke Tatsumura, Sadegh Yazdanshenas, Vaughn Betz
2016 B conf
FPL
Mohamed S. Abdelfattah, Vaughn Betz
2016 B conf
FPL
Ibrahim Ahmed, Shuze Zhao, Olivier Trescases, Vaughn Betz
2016 J jnl
ACM Trans. Reconfigurable Technol. Syst.
Henry Wong, Vaughn Betz, Jonathan Rose
2016 J jnl
IEEE Trans. Very Large Scale Integr. Syst.
Ehsan Nasiri, Javeed Shaikh, André Hahn Pereira, Vaughn Betz
2016 J jnl
IEEE Trans. Very Large Scale Integr. Syst.
Mohamed S. Abdelfattah, Vaughn Betz
2016 B conf
FPL
Oleg Petelin, Vaughn Betz
2015 conf
FPT
Andrew Bitar, Mohamed S. Abdelfattah, Vaughn Betz
2015 B conf
FPL
Mohamed S. Abdelfattah, Andrew Bitar, Ange Yaghi, Vaughn Betz
2015 conf
FPT
Kevin E. Murray, Vaughn Betz
2015 J jnl
IEEE Trans. Comput. Aided Des. Integr. Circuits Syst.
Michael Wainberg, Vaughn Betz
2015 A conf
FPGA
Mohamed S. Abdelfattah, Andrew Bitar, Vaughn Betz
2015 J jnl
ACM Trans. Reconfigurable Technol. Syst.
Kevin E. Murray, Scott Whitty, Suya Liu, Jason Luu, Vaughn Betz
2015 B conf
FPL
Oleg Petelin, Vaughn Betz
2014 A conf
FPGA
André Hahn Pereira, Vaughn Betz
2014 conf
FPT
Rafat Rashid, J. Gregory Steffan, Vaughn Betz
2014 conf
ANCS
Andrew Bitar, Jeffrey Cassidy, Natalie D. Enright Jerger, Vaughn Betz
2014 Misc conf
FCCM
Jeffrey Cassidy, Lothar Lilge, Vaughn Betz
2014 J jnl
ACM Trans. Reconfigurable Technol. Syst.
Mohamed S. Abdelfattah, Vaughn Betz
2014 Misc conf
FCCM
Jason Luu, Conor McCullough, Sen Wang, Safeen Huda, Bo Yan, Charles Chiasson, Kenneth B. Kent, Jason Helge Anderson, Jonathan Rose, Vaughn Betz
2014 J jnl
IEEE Trans. Very Large Scale Integr. Syst.
Henry Wong, Vaughn Betz, Jonathan Rose
2014 A conf
FPGA
Kevin E. Murray, Vaughn Betz
2014 Misc conf
FCCM
Matthew An, J. Gregory Steffan, Vaughn Betz
2014 A ed.
FPGA
Vaughn Betz, George A. Constantinides
2014 J jnl
IEEE Micro
Mohamed S. Abdelfattah, Vaughn Betz
2014 J jnl
ACM Trans. Reconfigurable Technol. Syst.
Jason Luu, Jeffrey Goeders, Michael Wainberg, Andrew Somerville, Thien Yu, Konstantin Nasartschuk, Miad Nasr, Sen Wang, Tim Liu, Nooruddin Ahmed, Kenneth B. Kent, Jason Helge Anderson, Jonathan Rose, Vaughn Betz
2013 A conf
FPGA
Vaughn Betz, Jason Cong
2013 conf
FPT
Charles Chiasson, Vaughn Betz
2013 conf
FPT
Henry Wong, Vaughn Betz, Jonathan Rose
2013 B conf
FPL
Kevin E. Murray, Scott Whitty, Suya Liu, Jason Luu, Vaughn Betz
2013 B conf
FPL
Charles Chiasson, Vaughn Betz
2013 A ed.
FPGA
Brad L. Hutchings, Vaughn Betz
2013 B conf
FPL
Mohamed S. Abdelfattah, Vaughn Betz
2013 B conf
FPL
Kevin E. Murray, Scott Whitty, Suya Liu, Jason Luu, Vaughn Betz
2012 conf
FPT
Mohamed S. Abdelfattah, Vaughn Betz
2012 J jnl
ACM Trans. Reconfigurable Technol. Syst.
Wei Zhang, Vaughn Betz, Jonathan Rose
2011 A conf
FPGA
Henry Wong, Vaughn Betz, Jonathan Rose
2011 J jnl
ACM Trans. Design Autom. Electr. Syst.
Adrian Ludwin, Vaughn Betz
2011 J jnl
IEEE Des. Test Comput.
Vaughn Betz
2010 A conf
FPGA
Doris Chen, Deshanand P. Singh, Jeffrey Chromczak, David M. Lewis, Ryan Fung, David Neto, Vaughn Betz
2010 conf
ERSA
Vaughn Betz, Stephen Brown
2009 ch.
Embedded Systems Design and Verification
Mike Hutton, Vaughn Betz
2009 B conf
FPL
Vaughn Betz
2008 A conf
FPGA
Adrian Ludwin, Vaughn Betz, Ketan Padalia
2008 conf
FPT
Wei Zhang, Vaughn Betz, Jonathan Rose
2008 J jnl
IEEE Trans. Comput. Aided Des. Integr. Circuits Syst.
Ryan Fung, Vaughn Betz, William Chow
2007 J jnl
IEEE Trans. Comput. Aided Des. Integr. Circuits Syst.
Russell Tessier, Vaughn Betz, David Neto, Aaron Egier, Thiagaraja Gopalsamy
2006 A conf
FPGA
Russell Tessier, Vaughn Betz, David Neto, Thiagaraja Gopalsamy
2005 A conf
FPGA
David M. Lewis, Elias Ahmed, Gregg Baeckler, Vaughn Betz, Mark Bourgeault, David Cashman, David R. Galloway, Mike Hutton, Christopher Lane, Andy Lee, Paul Leventis, Sandy Marquardt, Cameron McClintock, Ketan Padalia, Bruce Pedersen, Giles Powell, Boris Ratchev, Srinivas Reddy, Jay Schleicher, Kevin Stevens, Richard Yuan, Richard Cliff, Jonathan Rose
2004 A conf
ICCAD
Ryan Fung, Vaughn Betz, William Chow
2003 A conf
FPGA
David M. Lewis, Vaughn Betz, David Jefferson, Andy Lee, Christopher Lane, Paul Leventis, Sandy Marquardt, Cameron McClintock, Bruce Pedersen, Giles Powell, Srinivas Reddy, Chris Wysocki, Richard Cliff, Jonathan Rose
2000 A conf
FPGA
Vaughn Betz, Jonathan Rose
2000 J jnl
IEEE Trans. Very Large Scale Integr. Syst.
Alexander Marquardt, Vaughn Betz, Jonathan Rose
2000 A conf
FPGA
Alexander Marquardt, Vaughn Betz, Jonathan Rose
1999 book
Vaughn Betz, Jonathan Rose, Alexander Marquardt
1999 A conf
FPGA
Vaughn Betz, Jonathan Rose
1999 A conf
FPGA
Alexander Marquardt, Vaughn Betz, Jonathan Rose
1998 A conf
FPGA
Jordan S. Swartz, Vaughn Betz, Jonathan Rose
1998 J jnl
IEEE Trans. Very Large Scale Integr. Syst.
Vaughn Betz, Jonathan Rose
1998 J jnl
IEEE Des. Test Comput.
Vaughn Betz, Jonathan Rose
1997 B conf
FPL
Vaughn Betz, Jonathan Rose
1996 A conf
ICCAD
Vaughn Betz, Jonathan Rose
1995 A conf
FPGA
Vaughn Betz, Jonathan Rose
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