def encrypt(M: bytes, publicKey, saving: bool = False): """ Encrypt a message M to make him sendable. """ assert isinstance(M, bytes) n, e = publicKey def process(m): return ut.square_and_multiply(m, e, n) # First, turn M into int Mint = bm.bytes_to_int(M) if Mint < n: # That's a short message m = Mint e = process(m) else: # M is a longer message, so it's divided into blocks size = (it.getKeySize(publicKey) // 8) - 1 e = [process(bm.bytes_to_int(elt)) for elt in bm.splitBytes(M, size)] if saving: e = it.writeKeytoFile(e, "encrypted", config.DIRECTORY_PROCESSING, ".kat") return e
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
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
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
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
def x509(subjectPublicKey, name: str = "X509", out: bool = True): import base64 # Get key size's n = it.getKeySize(it.getIntKey(subjectPublicKey, 3)) CA_public_key, CA_private_key = elG.key_gen(n, primeFount=True) import os # An X. 509 Serial Number is an integer whose value can be represented in 20 bytes serialN = it.getB64Keys(os.urandom(20)) from datetime import date today = date.today() nextY = today.replace(year=today.year + 1) # The certificate is signed by the private key of the certification authority. # The one who manufactured and issued this certificate. signature = it.getB64Keys(elG.signing(subjectPublicKey, CA_private_key)) CA = f""" Certificate: Data: Version: 3 (0x2) Serial Number: {serialN} Signature Algorithm: El-Gamal Issuer Name: Country: FR Organization: Bark Trust Services Common Name = BARK CA 101 Validity Not Before: {today.strftime("%b-%d-%Y")} Not After: {nextY.strftime("%b-%d-%Y")} Subject: CN = Katsumi User Subject Public Key Info: Public Key Algorithm: El-Gamal Public-Key: ({str(n)} bit) pub: {base64.b64encode(subjectPublicKey).decode()} Signature Algorithm: El-Gamal {signature} Key Usages Purposes: Digital Signature """ if out: print(CA) else: from ressources import config # Write into file it.writeVartoFile(CA, name, config.DIRECTORY_PROCESSING, ".ca") return it.getB64Keys(CA_public_key)
def encrypt(M: bytes, publicKey, saving: bool = False): assert isinstance(M, bytes) or isinstance(M, bytearray) p, g, h = publicKey def process_of_c1_c2(m): y = rd.randrange(1, p - 1) # shared secret -> g^xy c1 = ut.square_and_multiply(g, y, p) s = ut.square_and_multiply(h, y, p) c2 = (m * s) % p return (c1, c2) Mint = bm.bytes_to_int(M) if Mint < p: # That's a short message m = Mint e = process_of_c1_c2(m) else: # M is a longer message, so it's divided into blocks # You need to choose a different y for each block to prevent # from Eve's attacks. size = (it.getKeySize(publicKey) // 8) - 1 e = [ process_of_c1_c2(bm.bytes_to_int(elt)) for elt in bm.splitBytes(M, size) ] if saving: e = it.writeKeytoFile(e, "encrypted", config.DIRECTORY_PROCESSING, ".kat") return e