Пример #1
0
def PoW(block, zBits=1, interruptOnChange=("", 0)):
    """
    Find a salt for which the md5 hash ends with zBits null

    block: bytearray of data
    zBits: number of ending null bits

    return [block|salt]
    """

    import random
    from ressources import config as c

    if interruptOnChange[0]:
        originalData = getattr(locals()["c"], interruptOnChange[0])[interruptOnChange[1]].copy()

    if zBits >= 255:
        raise ValueError("The number of zero bits must be lower than 2^8")

    salt = 1
    H = sponge(block + bm.mult_to_bytes(salt), 256)

    while not nullBits(H, zBits):

        if interruptOnChange[0]:
            if originalData != getattr(locals()["c"], interruptOnChange[0])[interruptOnChange[1]]:
                return False

        salt = random.randint(0, 1 << 32)
        H = sponge(block + bm.mult_to_bytes(salt), 256)

    return bm.mult_to_bytes(salt)
Пример #2
0
def invertGalois2(toInv: object):
    """
    Invert given {array of bits, bytes, int} in GF()

    ! You need to initialize the Galois_Field before !
    ! You need to have a dictionary file available !

    Output: bytes

    """

    d = int(config.DEGREE / 8)
    toInv = bm.mult_to_bytes(toInv)

    if config.GALOIS_WATCH or config.IN_CREATION:
        config.WATCH_INVERSION_NUMBER += 1
        exTime = time.time()

        # A(x) . A(x)^-1 congruent to 1 mod P(x)
        # where P(x) irreductible polynomial of given degree
        # A ^ p^n - 2 = inverted

        inv = poly_exp_mod_2(bm.bytes_to_int(toInv), config.NBR_ELEMENTS - 2,
                             config.IRRED_POLYNOMIAL)
        inv = inv.to_bytes(bm.bytes_needed(inv), "big")

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

    else:
        inv = config.INVERSIONS_BOX[bm.bytes_to_int(toInv)]

    return bm.zfill_b(inv, d)
Пример #3
0
def verifying(M: bytes, sign: int, pK: tuple = None):
    """
    Verify given signature of message M with corresponding public key's.
    """

    assert isinstance(M, (bytes, bytearray))

    from ..hashbased import hashFunctions as hashF

    if not pK:
        pK = it.extractKeyFromFile("public_key")

    size = it.getKeySize(pK)

    hm = hashF.sponge(M, size)
    # base64 to int
    hm = bm.bytes_to_int(bm.mult_to_bytes(hm))

    # If the signature is in base64
    if not isinstance(sign, int):
        sign = it.getIntKey(sign)

    n, e = pK
    # raises the signature to the power of e (modulo n)
    # (as when encrypting a message)
    if sign > n:
        print("Signature > modulus")

    test = ut.square_and_multiply(sign, e, n)

    if test == (hm % n):
        return True

    return False
Пример #4
0
def IV(arr, key="y/B?E(H+MbQeThVm".encode()):
    """
    The IV must, in addition to being unique, be unpredictable at encryption time.

    Return a 8 bytes array.
    """

    # Select a random encrypted message as initial vector to transform.
    import secrets as sr

    r1 = sr.randbelow(len(arr))
    r2 = sr.randbits(8)
    message = bm.bytes_to_int(arr[r1]) ^ r2
    message = bm.mult_to_bytes(message)

    # Let's use the principle of hmac
    # The basic idea is to concatenate the key and the message, and hash them together.
    # https://pymotw.com/3/hmac/

    import hmac
    import hashlib

    # Default algorithm for hmac is MD5, it's not the most secure
    # so let's use SHA-1

    digest_maker = hmac.new(key, message, hashlib.sha1)
    digest = digest_maker.hexdigest()

    return bytearray(bytes.fromhex(digest)[:8])
Пример #5
0
def signing(M: bytes, privateK: tuple = None, saving: bool = False, Verbose: bool = False):
    """
    Signing the message (M).
    You need to attach this signature to the message.
    """

    assert isinstance(M, bytes)

    from ..hashbased import hashFunctions as hashF

    if not privateK:
        privateK = it.extractKeyFromFile("private_key")

    size = it.getKeySize(privateK)  # Get key size

    if Verbose:
        print("Hashing in progress...")

    hm = hashF.sponge(M, size)
    # base64 to int
    hm = bm.bytes_to_int(bm.mult_to_bytes(hm))

    if Verbose:
        print(f"hm = {hm}")
        print("Hashing done.\n")

    # raises it to the power of d (modulo n)
    # same thing as decrypting
    n, d = privateK
    sign = ut.square_and_multiply(hm, d, n)

    if saving:
        sign = it.writeKeytoFile(sign, "RSA_signature")

    return sign
Пример #6
0
def verifying(M: bytes, sign: tuple, publicKey: tuple = None):
    """
    Verify given signature of message M with corresponding public key's.
    """
    assert isinstance(M, (bytes, bytearray))

    from ..hashbased import hashFunctions as hashF

    if not publicKey:
        publicKey = it.extractKeyFromFile("public_key")

    p, g, h = publicKey
    size = it.getKeySize(publicKey)

    hm = hashF.sponge(M, size)

    hm = bm.bytes_to_int(bm.mult_to_bytes(hm))

    if not isinstance(sign, tuple):
        b64data = sign
        sign = it.getIntKey(b64data[1:], b64data[0])

    s1, s2 = sign

    if (0 < s1 < p) and (0 < s2 < p - 1):

        test1 = (ut.square_and_multiply(h, s1, p) *
                 ut.square_and_multiply(s1, s2, p)) % p
        test2 = ut.square_and_multiply(g, hm, p)

        if test1 == test2:
            return True
        return False

    raise ValueError
Пример #7
0
def signing(M: bytes,
            privateK: tuple = None,
            saving: bool = False,
            Verbose: bool = False):
    """
    Signing a message M (bytes).
    """

    from ..hashbased import hashFunctions as hashF

    # y choosed randomly between 1 and p-2 with condition than y coprime to p-1
    if not privateK:
        privateK = it.extractKeyFromFile("private_key")

    p, g, x = privateK

    size = it.getKeySize(privateK)

    # M = bm.fileToBytes(M)
    # M = "Blablabla".encode()

    if Verbose:
        print("Hashing in progress...")

    hm = hashF.sponge(M, size)
    # #base64 to int
    hm = bm.bytes_to_int(bm.mult_to_bytes(hm))

    if Verbose:
        print("Hashing done.\n")

    p1 = p - 1

    k = rd.randrange(2, p - 2)

    while not ut.coprime(k, p1):
        k = rd.randrange(2, p - 2)

    if Verbose:
        print(f"Your secret integer is: {k}")

    s1 = ut.square_and_multiply(g, k, p)

    s2 = (multGroup.inv(k, p1) * (hm - x * s1)) % p1

    # In the unlikely event that s2 = 0 start again with a different random k.

    if s2 == 0:
        if Verbose:
            print("Unlikely, s2 is equal to 0. Restart signing...")
        signing(M, privateK, saving, Verbose)

    else:
        sign = (s1, s2)

        if saving:
            sign = it.writeKeytoFile(sign, "elG_signature")

        return sign
Пример #8
0
    def process(cipherT):
        c1, c2 = cipherT

        s1 = ut.square_and_multiply(c1, p - 1 - x, p)

        # This calculation produces the original message
        m = (c2 * s1) % p

        return bm.mult_to_bytes(m)
Пример #9
0
    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)
Пример #10
0
def genInverses2():
    """Generates a list of elements and their respective inverses."""

    print("\n\t || Inverses are going to be generated || \n")
    config.IN_CREATION = True

    config.INVERSIONS_BOX = [
        invertGalois2(bm.mult_to_bytes(elt)) for elt in config.ELEMENTS
    ]
    it.writeVartoFile(config.INVERSIONS_BOX, "inversion_Sbox")

    config.IN_CREATION = False
    print("\n\t || Inverses are generated || \n")
Пример #11
0
def GF2(degree):
    """Initialize the Galois Field GF(p^degree) in Zn."""
    config.DEGREE = degree
    config.NBR_ELEMENTS = 2**degree
    config.IRRED_POLYNOMIAL = int.from_bytes(
        bm.mult_to_bytes(config.IRRED_POLYNOMIAL), "big")
    config.GENERATOR = gen_GL_2(config.IRRED_POLYNOMIAL, degree)

    it.handleInvBox()

    if config.IN_CREATION:
        start = time.time()

        while config.IN_CREATION:
            it.clear()
            print(" --- Wait for the creation please --- ")
            print((" --- Time elapsed: {:.1f} seconds").format(time.time() -
                                                               start))
            time.sleep(1)
Пример #12
0
def getB64Keys(key):
    """
    Received in input key in tuple, bytes, list etc. and return key in base64.
    """
    import base64

    if isinstance(key, tuple):

        tw = bytearray()
        sizes = []

        for k in key:
            s = bm.bytes_needed(k)
            sizes.append(s)
            # Put the size into the coded b64
            tw += s.to_bytes(2, "big")

        for i, k in enumerate(key):
            tw += k.to_bytes(sizes[i], "big")

    elif isinstance(key, list):
        # E.g, ElGamal with M >= p (longer message)

        e = [getB64Keys(el) for el in key]

        tw = ""
        for el in e:
            tw += f"{el}|"

        tw = tw[:-1].encode()
    elif isinstance(key, bytes):
        # Already into bytes
        tw = key
    else:
        # uniq key
        tw = bm.mult_to_bytes(key)

    return base64.b64encode(tw).decode()
Пример #13
0
def md5(block):
    """
    Return md5 hash

    block: bytearray of data to hash
    """

    import math

    # Done using the Wikipedia algorithm

    def iToB(i):
        return int.to_bytes(i, 4, "little")

    def p32(a, b):
        return (a + b) % (1 << 32)

    s = [
        7,
        12,
        17,
        22,
        7,
        12,
        17,
        22,
        7,
        12,
        17,
        22,
        7,
        12,
        17,
        22,
        5,
        9,
        14,
        20,
        5,
        9,
        14,
        20,
        5,
        9,
        14,
        20,
        5,
        9,
        14,
        20,
        4,
        11,
        16,
        23,
        4,
        11,
        16,
        23,
        4,
        11,
        16,
        23,
        4,
        11,
        16,
        23,
        6,
        10,
        15,
        21,
        6,
        10,
        15,
        21,
        6,
        10,
        15,
        21,
        6,
        10,
        15,
        21,
    ]

    K = []
    for i in range(64):
        K.append((math.floor(2 ** 32 * abs(math.sin(i + 1)))) % (1 << 32))

    iN = bm.bytes_to_int(block)
    lN = len(block) * 8

    # Number of 0 to add
    b = 512 - ((lN + 1) % 512)

    lN = int.from_bytes(lN.to_bytes(8, byteorder="little"), byteorder="big", signed=False)

    iN = (((iN << 1) | 1) << b) ^ lN

    block = bm.mult_to_bytes(iN)

    b512 = bm.splitBytes(block, 64)

    h1 = 0x67452301
    h2 = 0xEFCDAB89
    h3 = 0x98BADCFE
    h4 = 0x10325476

    for b5 in b512:

        blocks = bm.splitBytes(b5, 4)

        A = h1
        B = h2
        C = h3
        D = h4

        for i in range(64):
            if i <= 15:
                F = (B & C) | (~B & D)
                g = i
            elif i <= 31:
                F = (D & B) | (~D & C)
                g = (5 * i + 1) % 16
            elif i <= 47:
                F = B ^ C ^ D
                g = (3 * i + 5) % 16
            else:
                # C xor (B or (not D))
                F = C ^ (B | ~D) % (1 << 32)
                g = (7 * i) % 16

            # F + A + K[i] + M[g]
            try:
                F = p32(p32(p32(F, A), K[i]), int.from_bytes(blocks[g], "little"))
            except IndexError:
                print(i, K, blocks[g])
                raise Exception("Error")

            A = D
            D = C
            C = B
            # B + leftrotate(F, s[i])
            B = p32(B, ((F << s[i]) | (F >> (32 - s[i]))))

        h1 = p32(A, h1)
        h2 = p32(B, h2)
        h3 = p32(C, h3)
        h4 = p32(D, h4)

    return bm.packSplittedBytes([iToB(h1), iToB(h2), iToB(h3), iToB(h4)])
Пример #14
0
 def process(cipherT):
     un = ut.square_and_multiply(cipherT, d, n)
     return bm.mult_to_bytes(un)