Beispiel #1
0
    def GHASH64(H, A, C, X, i):
        n = len(C)
        m = len(A)

        if i <= m:
            # A1 = A[1-1]
            return gz2.poly_mult_mod_2(
                bm.bytes_to_int(bm.b_op(X, A[i - 1], "XOR")), H, p)

        if i <= m + n:
            return gz2.poly_mult_mod_2(
                bm.bytes_to_int(bm.b_op(X, C[i - m - 1], "XOR")), H, p)

        if i == m + n + 1:
            return gz2.poly_mult_mod_2(
                a=bm.bytes_to_int(
                    bm.b_op(
                        b1=gz2.poly_mult_mod_2(
                            bm.bytes_to_int(bm.b_op(X, lenb(A), "XOR")), H,
                            p).to_bytes(8, "big"),
                        b2=lenb(C),
                        ope="XOR",
                    )),
                b=H,
                mod=p,
            )
Beispiel #2
0
def FO(pKO, pKI, arr):

    if len(arr) != 4:
        raise ValueError("FO takes 32 bits as 4 bytes array in input")

    arr = bm.splitBytes(arr, 2)
    left = arr[0]
    right = arr[1]

    for i in range(0, 3):
        left = right
        right = bm.b_op(right, FI(bm.b_op(left, pKO[i], "XOR"), pKI[i]), "XOR")

    return left + right
Beispiel #3
0
def kasumi(arr, encrypt=True):
    if len(arr) > 8:
        raise ValueError("Error: Kasumi takes 64 bits as 8 bytes array in input")

    config.WATCH_KASUMI_NUMBER += 1
    exTime = time.time()

    arr = bm.splitBytes(arr, 4)
    left = arr[0]
    right = arr[1]

    for i in range(0, 8):

        if not encrypt:
            i = 7 - i

        KO = [config.KO1[i], config.KO2[i], config.KO3[i]]
        KI = [config.KI1[i], config.KI2[i], config.KI3[i]]
        KL = [config.KL1[i], config.KL2[i]]
        lp = left

        if i % 2 == 0:
            left = FL(KL, FO(KO, KI, left))
        else:
            left = FO(KO, KI, FL(KL, left))

        left = bm.b_op(left, right, "XOR")
        right = lp

    config.WATCH_GLOBAL_KASUMI += time.time() - exTime

    return right + left
Beispiel #4
0
def FL(pKL, arr):

    if len(arr) != 4:
        raise ValueError("FL takes 32 bits as 4 bytes array in input")

    arr = bm.splitBytes(arr, 2)
    left = arr[0]
    right = arr[1]

    rp = bm.b_op(bm.circularRotation(bm.b_op(left, pKL[0], "AND"), 0, 1), right, "XOR")
    lp = bm.b_op(bm.circularRotation(bm.b_op(rp, pKL[1], "OR"), 0, 1), left, "XOR")

    # Inverted in Galois Field
    lp = invertGalois2(lp)
    rp = invertGalois2(rp)

    return lp + rp
Beispiel #5
0
def FI(b1, pKI):

    b1 = bm.circularRotation(b1, 1, 2)

    z = bm.splitBytes(pKI, 1)

    subZ1 = S1[int.from_bytes(z[0], "big")].to_bytes(1, "big")
    subZ2 = S2[int.from_bytes(z[1], "big")].to_bytes(1, "big")

    return bm.b_op(b1, subZ1 + subZ2, "XOR")
Beispiel #6
0
def CBC(arr, encrypt=True):
    """In CBC mode, each block of plaintext is XORed with the previous ciphertext block before being encrypted. """

    # Initialisation Vector
    if encrypt:
        iv = IV(arr)
    else:
        iv = IV_action(arr)

    res = []

    for i, message in enumerate(arr):

        config.WATCH_PERCENTAGE = ((len(arr) -
                                    (len(arr) - i)) / len(arr)) * 100
        exTime = time.time()

        if i == 0:
            # Initialization
            if encrypt:
                res.append(kasu.kasumi(bm.b_op(iv, message, "XOR")))
            else:
                res.append(bm.b_op(kasu.kasumi(message, False), iv, "XOR"))
        else:
            if encrypt:
                res.append(kasu.kasumi(bm.b_op(res[i - 1], message, "XOR")))
            else:
                res.append(
                    bm.b_op(kasu.kasumi(message, False), arr[i - 1], "XOR"))

        config.WATCH_GLOBAL_CIPHER += time.time() - exTime
        config.WATCH_BLOC_CIPHER = config.WATCH_GLOBAL_CIPHER / (i + 1)
        config.WATCH_BLOC_KASUMI = config.WATCH_GLOBAL_KASUMI / (i + 1)

    if encrypt:
        # Adding the IV to the encrypted data
        res = IV_action(res, iv, "store")

    return res
Beispiel #7
0
def CTR(arr, encrypt=True):
    """
    Counter Mode is xoring the message with a encrypted counter (IV + incr(0))

    arr: array of bytearray of 8 bytes of data to encrypt/decrypt
    encrypt: true to encrypt
    """

    if encrypt:
        iv = IV(arr)
    else:
        iv = IV_action(arr)

    res = []

    for i, message in enumerate(arr):

        config.WATCH_PERCENTAGE = ((len(arr) -
                                    (len(arr) - i)) / len(arr)) * 100
        exTime = time.time()

        noc = bm.b_op(iv, (i + 1).to_bytes(8, "big"), "XOR")
        kas = kasu.kasumi(noc, True)
        coded = bm.b_op(message, kas, "XOR")

        res.append(coded)

        config.WATCH_GLOBAL_CIPHER += time.time() - exTime
        config.WATCH_BLOC_CIPHER = config.WATCH_GLOBAL_CIPHER / (i + 1)
        config.WATCH_BLOC_KASUMI = config.WATCH_GLOBAL_KASUMI / (i + 1)

    if encrypt:
        # Adding the IV to the encrypted data
        IV_action(res, iv, "store")

    return res
Beispiel #8
0
def sponge(N: bytearray, d: int):
    """
    Sponge construction for hash functions.

    N: Thing to hash \n
    d: size of hash wanted \n

    return bytearray
    """

    def pad(N, r):
        iN = bm.bytes_to_int(N)
        lN = int.bit_length(iN)

        # Number of 0 to add
        b = (r - ((lN + 3) % r)) % r

        # Padding using the SHA-3 pattern 10*1: a 1 bit, followed by zero or more 0 bits (maximum r − 1) and a final 1 bit.
        op = ((iN | (1 << b + lN + 1)) << 1) ^ 1

        return bm.mult_to_bytes(op)

    r = 8
    d = int(d / 8)

    blocks = bm.splitBytes(pad(N, r * 8), r)

    S = bytearray(16)

    # Absorbing
    for block in blocks:
        S[:r] = bm.b_op(S[:r], block)
        S = md5(S)

    O = bytearray()
    # Squeezing

    while len(O) < d:
        O += S[:r]
        S = md5(S)

    # Truncating with the desired length
    return O[:d]
Beispiel #9
0
def set_key(km=config.KEY):
    """Kasumi's keyscheduler."""

    # Chosen as a "nothing up my sleeve" number
    nums = b"\x124Vx\x9a\xbc\xde\xff\xed\xcb\xa9\x87eC!\x00"

    # Additionally a modified key K', similarly divided into 16-bit sub keys K'i, is used.
    kp = bm.b_op(km, nums, "XOR")

    # The 128-bit key K is divided into eight 16-bit sub keys Ki
    skm, skp = bm.splitBytes(km, 2), bm.splitBytes(kp, 2)

    config.KL1 = [bytearray(bm.circularRotation(skm[x], 0, 1)) for x in range(0, 8)]
    config.KL2 = [skp[(x + 2) % 8] for x in range(0, 8)]
    config.KO1 = [bytearray(bm.circularRotation(skm[(x + 1) % 8], 0, 5)) for x in range(0, 8)]
    config.KO2 = [bytearray(bm.circularRotation(skm[(x + 5) % 8], 0, 8)) for x in range(0, 8)]
    config.KO3 = [bytearray(bm.circularRotation(skm[(x + 6) % 8], 0, 13)) for x in range(0, 8)]
    config.KI1 = [skp[(x + 4) % 8] for x in range(0, 8)]
    config.KI2 = [skp[(x + 3) % 8] for x in range(0, 8)]
    config.KI3 = [skp[(x + 7) % 8] for x in range(0, 8)]

    # SBoxes initialization considering the given master key !
    initRC4(km)
Beispiel #10
0
def GCM(arr, encrypt=True, aad=""):
    """
    GCM is CTR mode with authentification of additional data (AAD) authenticated with multiplication in a Galois Field

    arr: array of bytearray of 8 bytes of data to encrypt/decrypt
    encrypt: boolean, true to encypt
    aad: string of additional authenticated data
    """

    if encrypt:
        iv = IV(arr)
    else:
        iv = IV_action(arr)
        # Integrity Check Balue
        icv = IV_action(arr)

    # Additional authenticated data (AAD), which is denoted as A
    A = []

    if encrypt:
        if aad != "":
            aadc = aad.encode()

            if len(aadc) > 1 << 64:
                raise Exception("Too much AAD")

            A = bm.splitBytes(aadc, 8)
            A[-1] = bm.zfill_b(A[-1], 8)
    else:
        header = arr[0]
        epos = int.from_bytes(header, "big")
        A = arr[1:epos]
        arr = arr[epos:]

    # Encrypted message
    C = []

    # 1 + α + α3 + α4 + α64 - 64 field polynomial
    p = int(
        "10000000000000000000000000000000000000000000000000000000000001111", 2)

    def lenb(i):
        return (len(i) * 8).to_bytes(8, "big")

    def GHASH64(H, A, C, X, i):
        n = len(C)
        m = len(A)

        if i <= m:
            # A1 = A[1-1]
            return gz2.poly_mult_mod_2(
                bm.bytes_to_int(bm.b_op(X, A[i - 1], "XOR")), H, p)

        if i <= m + n:
            return gz2.poly_mult_mod_2(
                bm.bytes_to_int(bm.b_op(X, C[i - m - 1], "XOR")), H, p)

        if i == m + n + 1:
            return gz2.poly_mult_mod_2(
                a=bm.bytes_to_int(
                    bm.b_op(
                        b1=gz2.poly_mult_mod_2(
                            bm.bytes_to_int(bm.b_op(X, lenb(A), "XOR")), H,
                            p).to_bytes(8, "big"),
                        b2=lenb(C),
                        ope="XOR",
                    )),
                b=H,
                mod=p,
            )

    H = bm.bytes_to_int(kasu.kasumi(b"\x00" * 8))

    Y = GHASH64(H, b"", [iv], b"\x00", 1).to_bytes(8, "big")
    E0 = kasu.kasumi(Y)

    n = len(arr)
    m = len(A)

    # equivalent of CTR mode
    for i in range(n):
        config.WATCH_PERCENTAGE = (((n * 2 + m + 1) - ((n * 2 + m + 1) - i)) /
                                   (n * 2 + m + 1)) * 100
        exTime = time.time()

        # treats the rightmost 32bits of its argument as a nonnegative integer with the least significant bit on the right, and increments this value modulo 2^32
        Y = Y[:4] + (
            (int.from_bytes(Y[-4:], "big") + 1) % 1 << 32).to_bytes(4, "big")
        E = kasu.kasumi(Y)

        C.append(bm.b_op(arr[i], E, "XOR"))

        config.WATCH_GLOBAL_CIPHER += time.time() - exTime
        config.WATCH_BLOC_CIPHER = config.WATCH_GLOBAL_CIPHER / (i + 1)
        config.WATCH_BLOC_KASUMI = config.WATCH_GLOBAL_KASUMI / (i + 1)

    res = C

    # plaintext is in C when we decrypt, me must replace it with the ciphertext
    if not encrypt:
        C = arr

    # first init of X = GHASH64(i=0) = b'\x00'
    X = b"\x00"

    for i in range(n + m + 1):
        config.WATCH_PERCENTAGE = (((n * 2 + m + 1) - ((n * 2 + m + 1) -
                                                       (i + n))) /
                                   (n * 2 + m + 1)) * 100
        exTime = time.time()

        X = GHASH64(H, A, C, X, i + 1).to_bytes(8, "big")

        config.WATCH_GLOBAL_CIPHER += time.time() - exTime
        config.WATCH_BLOC_CIPHER = config.WATCH_GLOBAL_CIPHER / (i + 1)

    icvc = bm.b_op(E0, X, "XOR")

    if not encrypt:
        if icv != icvc:
            print(
                "\nYELLOW: INTEGRITY CHECK CONTROL INCORRECT, AAD HAVE BEEN MODIFIED !!"
            )

    if encrypt:
        IV_action(res, icvc, "store")
        # Adding the IV to the encrypted data
        IV_action(res, iv, "store")

        header = (1 + len(A)).to_bytes(8, "big")
        res = [header] + A + res

    return res