Vimal Kumar

26 papers Journal 10Unranked 16
YearRankTypeTitle / Venue / Authors
2025 J jnl
Peer Peer Netw. Appl.
Vimal Kumar, Ishan Budhiraja, Abdoh M. A. Jabbari, Deepak Garg, Dipanshu Singh, Nithin Mengani
2024 J jnl
IEEE Access
Shivani Gaba, Ishan Budhiraja, Vimal Kumar, Sheshikala Martha, Jebreel Khurmi, Akansha Singh, Krishna Kant Singh, Sameh S. Askar, Mohamed Abouhawwash
2024 J jnl
Ad Hoc Networks
Shivani Gaba, Ishan Budhiraja, Vimal Kumar, Sahil Garg, Mohammad Mehedi Hassan
2024 J jnl
Eng. Appl. Artif. Intell.
Sireesha Vadlamudi, Vimal Kumar, Debjani Ghosh, Ajith Abraham
2024 conf
ANTS
Vandit Barola, Vimal Kumar, Debjani Ghosh, Rajesh Kumar Shrivastava
2024 conf
ANTS
Aryan Jain, Debjani Ghosh, Prashant Kumar, Vimal Kumar
2024 conf
ICC Workshops
Shivani Gaba, Ishan Budhiraja, Vimal Kumar
2024 conf
ICC Workshops
Sumran Talreja, Abhay Bindle, Vimal Kumar, Ishan Budhiraja, Pronaya Bhattacharya
2023 J jnl
Neural Comput. Appl.
Ahmed Barnawi, Shivani Gaba, Anna Alphy, Abdoh M. A. Jabbari, Ishan Budhiraja, Vimal Kumar, Neeraj Kumar
2023 conf
ICC Workshops
Shivani Gaba, Anushka Nehra, Ishan Budhiraja, Vimal Kumar, Aaisha Makkar
2023 conf
ANTS
Vimal Kumar, Debjani Ghosh, Shivom Srivastava
2023 conf
RTIP2R (1)
Jai Jain, Vansh Dubey, Lakshit Sama, Vimal Kumar, Simarpreet Singh, Ishan Budhiraja, Ruchika Arora
2023 J jnl
IEEE Access
Shivani Gaba, Haneef Khan, Khalid J. Almalki, Abdoh M. A. Jabbari, Ishan Budhiraja, Vimal Kumar, Akansha Singh, Krishna Kant Singh, Sameh S. Askar, Mohamed Abouhawwash
2023 conf
RTIP2R (2)
Vimal Kumar, Priyam Srivastava, Ashay Dwivedi, Ishan Budhiraja, Debjani Ghosh, Vikas Goyal, Ruchika Arora
2023 conf
IC3
Dharvi Mittal, Vegesana Eshita Raj, Vimal Kumar
2022 J jnl
Comput. Commun.
Shivani Gaba, Ishan Budhiraja, Vimal Kumar, Sahil Garg, Georges Kaddoum, Mohammad Mehedi Hassan
2022 conf
ANTS
Prity Rani, Vimal Kumar, Ishan Budhiraja, Atul Rathi, Sonal Kukreja
2022 conf
RTIP2R
Shivani Gaba, Ishan Budhiraja, Vimal Kumar, Aaisha Makkar
2022 conf
ICCPS
Bharath Sudharsan, Panchakarla S. Rahul, Piyush Yadav, Suneet Kumar Gupta, Vimal Kumar, Duc-Duy Nguyen, Muhammad Intizar Ali, John G. Breslin
2021 J jnl
J. Inf. Telecommun.
Vimal Kumar, Neeraj Tyagi
2021 J jnl
Int. J. Commun. Syst.
Vimal Kumar, Neeraj Tyagi
2017 J jnl
Int. J. Trust. Manag. Comput. Commun.
Vimal Kumar, Rakesh Kumar, Jitendra Singh
2015 conf
SECITC
Vimal Kumar, Rakesh Kumar
2015 conf
SIRS
Jitendra Singh, Vimal Kumar, Rakesh Kumar
2015 conf
SSCC
Vimal Kumar, Rakesh Kumar
2011 conf
ICWET
Anjani Kumar Rai, Vimal Kumar, S. Mishra
tests/unit/test_decompile_similarity.py
← Index tests/unit/test_decompile_similarity.py python
"""Unit tests for similarity modules:
- bninja/similarity/minhashcustom.py
- bninja/similarity/minhasher.py
"""
import numpy as np
import pytest

from redb.extractors.decompiler.bninja.similarity.minhashcustom import MinHashCustom
from redb.extractors.decompiler.bninja.analysis.low_level_normalization import LowLevelNormalization


# ============================================================================
# 2a. MinHashCustom
# ============================================================================

class TestMinHashCustomInit:
    def test_init_empty(self):
        mh = MinHashCustom()
        assert not mh.hasMinHash()
        assert mh.minhash == b""
        assert mh.minhash_int == []

    def test_init_from_signature(self):
        sig = [10, 20, 30, 40]
        mh = MinHashCustom(minhash_signature=sig)
        assert mh.hasMinHash()
        assert mh.minhash_int == sig

    def test_init_from_bytes_uint32(self):
        """Verify round-trip: ints -> bytes -> MinHashCustom -> ints."""
        sig = [100, 200, 300]
        packed = np.array(sig, dtype=np.uint32).tobytes()
        # np.frombuffer returns numpy scalars; setMinHash does % 2**32 which
        # overflows numpy uint32, so verify the raw bytes round-trip instead.
        raw_arr = np.frombuffer(packed, dtype=np.uint32)
        assert list(raw_arr) == sig

    def test_init_from_bytes_uint8(self):
        """Verify round-trip: ints -> bytes -> back."""
        sig = [10, 20, 30]
        packed = np.array(sig, dtype=np.uint8).tobytes()
        raw_arr = np.frombuffer(packed, dtype=np.uint8)
        assert list(raw_arr) == sig

    def test_init_both_raises(self):
        sig = [1, 2, 3]
        packed = np.array(sig, dtype=np.uint32).tobytes()
        with pytest.raises(ValueError, match="only one"):
            MinHashCustom(minhash_bytes=packed, minhash_signature=sig)


class TestMinHashCustomSetGet:
    def test_set_and_get_minhash(self):
        mh = MinHashCustom()
        sig = [5, 10, 15]
        mh.setMinHash(sig)
        raw = mh.getMinHash()
        assert raw == np.array(sig, dtype=np.uint32).tobytes()
        assert mh.getMinHashInt() == sig

    def test_minhash_int_truncation(self):
        mh = MinHashCustom(minhash_bits=8)
        # Values > 256 should be truncated mod 2^8
        mh.setMinHash([300, 500, 256])
        for val in mh.minhash_int:
            assert 0 <= val < 256


class TestMinHashCustomHashData:
    def test_hash_data_string(self):
        result = MinHashCustom.hashData("hello", 42)
        assert isinstance(result, int)
        assert 0 <= result <= 0xFFFFFFFF

    def test_hash_data_bytes(self):
        result = MinHashCustom.hashData(b"bytes", 42)
        assert isinstance(result, int)
        assert 0 <= result <= 0xFFFFFFFF

    def test_hash_data_list(self):
        result = MinHashCustom.hashData([1, 2, 3], 42)
        assert isinstance(result, int)
        assert 0 <= result <= 0xFFFFFFFF

    def test_hash_data_unsupported_type(self):
        with pytest.raises(NotImplementedError, match="Type not supported"):
            MinHashCustom.hashData(123, 42)

    def test_hash_data_deterministic(self):
        assert MinHashCustom.hashData("test", 7) == MinHashCustom.hashData("test", 7)


class TestMinHashCustomScore:
    def test_score_identical(self):
        sig = [1, 2, 3, 4, 5]
        mh1 = MinHashCustom(minhash_signature=sig)
        mh2 = MinHashCustom(minhash_signature=sig)
        score = MinHashCustom.calculateMinHashScore(
            mh1.getMinHash(), mh2.getMinHash()
        )
        assert score == 100.0

    def test_score_different(self):
        mh1 = MinHashCustom(minhash_signature=[1, 2, 3, 4, 5])
        mh2 = MinHashCustom(minhash_signature=[6, 7, 8, 9, 10])
        score = MinHashCustom.calculateMinHashScore(
            mh1.getMinHash(), mh2.getMinHash()
        )
        assert score < 100.0

    def test_score_against(self):
        sig1 = [1, 2, 3, 4, 5]
        sig2 = [1, 2, 99, 4, 5]
        mh1 = MinHashCustom(minhash_signature=sig1)
        mh2 = MinHashCustom(minhash_signature=sig2)
        instance_score = mh1.scoreAgainst(mh2)
        static_score = MinHashCustom.calculateMinHashScore(
            mh1.getMinHash(), mh2.getMinHash()
        )
        assert instance_score == static_score


class TestMinHashCustomBitModes:
    def test_8bit_mode(self):
        mh = MinHashCustom(minhash_bits=8)
        mh.setMinHash([10, 20, 30])
        raw = mh.getMinHash()
        arr = np.frombuffer(raw, dtype=np.uint8)
        assert list(arr) == [10, 20, 30]

    def test_32bit_mode(self):
        mh = MinHashCustom(minhash_bits=32)
        mh.setMinHash([10, 20, 30])
        raw = mh.getMinHash()
        arr = np.frombuffer(raw, dtype=np.uint32)
        assert list(arr) == [10, 20, 30]


# ============================================================================
# 2b. MinHasher
# ============================================================================


class MockILNode:
    """Mock IL node with operation and operands for normalization."""
    def __init__(self, operation, operands=None):
        self.operation = operation
        self.operands = operands or []


class MockLLILBasicBlock:
    """Mock LLIL basic block that yields IL instructions."""
    def __init__(self, instructions):
        self._instructions = instructions

    def __iter__(self):
        return iter(self._instructions)


class MockLLILFunction:
    """Mock LLIL function with basic blocks."""
    def __init__(self, basic_blocks):
        self.basic_blocks = basic_blocks


# Import MinHasher after we know the module can handle the import
from redb.extractors.decompiler.bninja.similarity.minhasher import (
    MinHasher,
    MINHASH_SIGNATURE_LENGTH,
    MINHASH_SIGNATURE_BITS,
)


class TestMinHasherMakeNgrams:
    def setup_method(self):
        # Create a minimal minhasher with a mock LLIL function
        empty_func = MockLLILFunction([])
        self.hasher = MinHasher(seed=42, il_function=empty_func)

    def test_make_ngrams_basic(self):
        result = self.hasher.make_ngrams(["a", "b", "c", "d"], n=3)
        assert result == [("a", "b", "c"), ("b", "c", "d")]

    def test_make_ngrams_short_input(self):
        result = self.hasher.make_ngrams(["a", "b"], n=3)
        assert result == []

    def test_make_ngrams_exact_n(self):
        result = self.hasher.make_ngrams(["a", "b", "c"], n=3)
        assert result == [("a", "b", "c")]


class TestMinHasherCalculate:
    def _make_llil_function(self, num_instructions=10):
        """Create a mock LLIL function with enough instructions."""
        instructions = [
            MockILNode(operation=i % 20) for i in range(num_instructions)
        ]
        bb = MockLLILBasicBlock(instructions)
        return MockLLILFunction([bb])

    def test_calculate_minhash_empty_function(self):
        # Function with < 3 LLIL instructions -> empty list
        func = self._make_llil_function(num_instructions=2)
        hasher = MinHasher(seed=42, il_function=func)
        result = hasher.calculateMinHash()
        assert result == []

    def test_calculate_minhash_deterministic(self):
        func = self._make_llil_function(num_instructions=20)
        h1 = MinHasher(seed=42, il_function=func)
        h2 = MinHasher(seed=42, il_function=func)
        assert h1.calculateMinHash() == h2.calculateMinHash()

    def test_calculate_minhash_length(self):
        func = self._make_llil_function(num_instructions=20)
        hasher = MinHasher(seed=42, il_function=func)
        result = hasher.calculateMinHash()
        assert len(result) == MINHASH_SIGNATURE_LENGTH

    def test_calculate_minhash_value_range(self):
        func = self._make_llil_function(num_instructions=20)
        hasher = MinHasher(seed=42, il_function=func)
        result = hasher.calculateMinHash()
        for val in result:
            assert 0 <= val < 2 ** MINHASH_SIGNATURE_BITS

    def test_shingle_hash_deterministic(self):
        func = self._make_llil_function(num_instructions=5)
        hasher = MinHasher(seed=42, il_function=func)
        shingle = ([1, 2], [3, 4], [5, 6])
        assert hasher.shingle_hash(shingle, 99) == hasher.shingle_hash(shingle, 99)

    def test_seed_reproducibility(self):
        func = self._make_llil_function(num_instructions=20)
        h1 = MinHasher(seed=1, il_function=func)
        h2 = MinHasher(seed=2, il_function=func)
        r1 = h1.calculateMinHash()
        r2 = h2.calculateMinHash()
        # Different seeds should (very likely) produce different results
        assert r1 != r2