Namita Mittal

68 papers B 1Journal 34Unranked 32
YearRankTypeTitle / Venue / Authors
2026 J jnl
J. Supercomput.
Siddhi Kumari Sharma, Lavika Goel, Namita Mittal
2025 J jnl
Int. J. Mach. Learn. Cybern.
Parvati Bhurani, Satyendra Singh Chouhan, Namita Mittal
2025 J jnl
Neural Comput. Appl.
Siddhi Kumari Sharma, Lavika Goel, Namita Mittal
2025 J jnl
Soc. Netw. Anal. Min.
Shikha Mundra, Namita Mittal, Richi Nayak
2024 J jnl
Multim. Tools Appl.
Geetanjali Singh, Namita Mittal, Satyendra Singh Chouhan
2024 J jnl
Multim. Tools Appl.
Sakshi Parashar, Namita Mittal, Parth Mehta
2024 J jnl
Multim. Tools Appl.
Megha Sharma, Namita Mittal, Anukram Mishra, Arun Gupta
2024 J jnl
ACM Trans. Asian Low Resour. Lang. Inf. Process.
Vijay Kumar Sharma, Namita Mittal, Ankit Vidyarthi, Deepak Gupta
2024 J jnl
ACM Trans. Asian Low Resour. Lang. Inf. Process.
Geetanjali Singh, Namita Mittal, Satyendra Singh Chouhan
2023 J jnl
ACM Trans. Asian Low Resour. Lang. Inf. Process.
Pawan Lahoti, Namita Mittal, Girdhari Singh
2023 J jnl
Multim. Tools Appl.
Shikha Mundra, Namita Mittal
2023 conf
CVIP (1)
Virendra Kumar Meghwal, Namita Mittal, Girdhari Singh
2023 J jnl
Int. J. Softw. Innov.
Megha Sharma, Namita Mittal, Anukram Mishra, Arun Gupta
2023 conf
IC3
Pawan Lahoti, Namita Mittal, Girdhari Singh
2023 J jnl
Multim. Tools Appl.
Vijay Kumar Sharma, Namita Mittal, Ankit Vidyarthi
2022 conf
CVIP (1)
Virendra Kumar Meghwal, Namita Mittal, Girdhari Singh
2022 J jnl
Soc. Netw. Anal. Min.
Shikha Mundra, Namita Mittal
2022 J jnl
Int. J. Softw. Sci. Comput. Intell.
Kapil Pareek, Arjun Choudhary, Ashish Tripathi, K. K. Mishra, Namita Mittal
2021 conf
IC3
Shikha Mundra, Namita Mittal
2021 conf
FIRE (Working Notes)
Shikha Mundra, Nikhil Singh, Namita Mittal
2021 J jnl
CoRR
Vedant Parikh, Vidit Mathur, Parth Mehta, Namita Mittal, Prasenjit Majumder
2021 conf
PReMI
Sakshi Parashar, Namita Mittal
2021 J jnl
ACM Trans. Asian Low Resour. Lang. Inf. Process.
Manju Lata Joshi, Nisheeth Joshi, Namita Mittal
2020 J jnl
Multim. Tools Appl.
Mithlesh Arya, Namita Mittal, Girdhari Singh
2020 J jnl
Vis. Comput.
Abhinav Agrawal, Namita Mittal
2019 J jnl
J. Intell. Fuzzy Syst.
Vijay Kumar Sharma, Namita Mittal
2018 J jnl
Computación y Sistemas
Vijay Kumar Sharma, Namita Mittal
2018 J jnl
CoRR
Lokesh Kumar Sharma, Namita Mittal
2018 J jnl
Computación y Sistemas
Lokesh Kumar Sharma, Namita Mittal, Anubha Aggarwal
2018 B conf
WI
Namita Mittal, Divya Sharma, Manju Lata Joshi
2018 J jnl
Comput. J.
Chandra Prakash, Rajesh Kumar, Namita Mittal
2018 J jnl
Artif. Intell. Rev.
Chandra Prakash, Rajesh Kumar, Namita Mittal
2018 J jnl
IET Comput. Vis.
Mithlesh Arya, Namita Mittal, Girdhari Singh
2017 conf
FIRE (Working Notes)
Manju Lata Joshi, Namita Mittal, Nisheeth Joshi
2017 conf
PReMI
Vijay Kumar Sharma, Namita Mittal
2017 J jnl
J. Intell. Fuzzy Syst.
Lokesh Kumar Sharma, Namita Mittal
2017 J jnl
J. Intell. Fuzzy Syst.
Ankit Vidyarthi, Namita Mittal
2016 J jnl
Comput. Methods Programs Biomed.
Ankit Vidyarthi, Namita Mittal
2016 conf
ICIA
Mithlesh Arya, Namita Mittal, Girdhari Singh
2016 conf
ICACDS
Abhishek Singh Kilak, Namita Mittal
2016 conf
ICIA
Harsha Gwalani, Namita Mittal, Ankit Vidyarthi
2016 conf
ICIA
Vijay Kumar Sharma, Namita Mittal
2016 book
Basant Agarwal, Namita Mittal
2016 J jnl
J. Exp. Theor. Artif. Intell.
Basant Agarwal, Namita Mittal
2016 conf
ICIA
Somya Gupta, Namita Mittal, Alok Kumar
2016 conf
ICIA
Candy Lalrempuii, Namita Mittal
2015 J jnl
Cogn. Comput.
Basant Agarwal, Soujanya Poria, Namita Mittal, Alexander F. Gelbukh, Amir Hussain
2015 conf
ICON
Lokesh Kumar Sharma, Namita Mittal
2015 conf
SocProS (1)
Chandra Prakash, Kanika Gupta, Rajesh Kumar, Namita Mittal
2015 conf
IC3
Chandra Prakash, Anshul Mittal, Rajesh Kumar, Namita Mittal
2015 J jnl
Comput. Intell. Neurosci.
Basant Agarwal, Namita Mittal, Pooja Bansal, Sonal Garg
2015 conf
ICSC
Lokesh Kumar Sharma, Namita Mittal
2014 J jnl
CoRR
Namita Mittal, Basant Agarwal, Ajay Gupta, Hemant Madhur
2014 conf
ICON
Lokesh Kumar Sharma, Namita Mittal
2013 conf
SocProS (1)
Ankit Vidyarthi, Namita Mittal
2013 conf
PReMI
Namita Mittal, Basant Agarwal, Garvit Chouhan, Prateek Pareek, Nitin Bania
2013 conf
ICDM Workshops
Basant Agarwal, Namita Mittal, Erik Cambria
2013 conf
CICLing (2)
Basant Agarwal, Namita Mittal
2013 conf
WASSA@NAACL-HLT
Basant Agarwal, Namita Mittal
2013 conf
ICACCI
Basant Agarwal, Vijay Kumar Sharma, Namita Mittal
2012 conf
SocProS
Basant Agarwal, Namita Mittal
2012 conf
SocProS
Basant Agarwal, Namita Mittal
2011 conf
IICAI
Namita Mittal, P. Ashok Rao, Srinivas Jinde, Abhinav Gupta, K. Adhikari
2011 conf
IICAI
Namita Mittal, Gaurav Gupta, Hemant Mangal
2011 J jnl
Int. J. Knowl. Web Intell.
Namita Mittal, Richi Nayak, Mahesh Chandra Govil, Kamal Chand Jain
2010 conf
Web Intelligence
Namita Mittal, Richi Nayak, Mahesh Chandra Govil, Kamal Chand Jain
2010 conf
A2CWiC
Namita Mittal, Richi Nayak, Mahesh Chandra Govil, Kamal Chand Jain
2010 conf
ICETET
Namita Mittal, Richi Nayak, Mahesh Chandra Govil, Kamal Chand Jain
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