<commit_before>"""
The NULL Crypto Protocol

This is a simple (and probably not very robust) ECDHE + AES protocol using ECDSA for authentication. Please don't use
this for anything important!!

The server has a list of trusted public keys, the client the public key of the server it trusts.

When connecting a new session, the client uses an ephemeral ECDH key signed by the client's long-term ECDSA key.
The server enforces that only one ephemeral ECDH key can be in use for each client key.

Handshake:
* Client sends it's pubkey and epehemeral pubkey, and sign the ephemeral pubkey and sends that.
* The client computes a shared secret to use as an AES128 key between the ephemeral ECDH key and the
  server's public key.
* If the server trusts the client's ECDSA key it computes the same shared secret using ECDH
* The server encrypts a random string using the shared key and sends it to the client.
* The client must decrypt and sign the plain text version of the string.
* The server verifies this final exchange and trusts the client.

"""

import os
import identity
import hashlib
import pyaes
import uuid

KDFS = [
    "NULLAES128sha256str"
]
DEFAULT_KDF = "NULLAES128sha256str"


def aes_encrypt_str(key, plaintext):
    """
    Encrypt a string with AES.
    :param key:
    :param plaintext:
    :return:
    """
    iv = os.urandom(16)
    encrypter = pyaes.Encrypter(pyaes.AESModeOfOperationCBC(key, iv))
    ctext = encrypter.feed(plaintext)
    ctext += encrypter.feed()
    return ctext, iv


def aes_decrypt_str(key, iv, ciphertext):
    """
    Decrypt a string with AES
    :param key:
    :param iv:
    :param ciphertext:
    :return:
    """
    decrypter = pyaes.Decrypter(pyaes.AESModeOfOperationCBC(key, iv))
    ptext = decrypter.feed(ciphertext)
    ptext += decrypter.feed()
    return ptext


def derive_key(kdf, shared):
    """
    Derive our secret key
    :param kdf:
    :param shared: shared secret ecpoints
    :return:<commit_msg>hexlified transmissable things<commit_after>"""
The NULL Crypto Protocol

This is a simple (and probably not very robust) ECDHE + AES protocol using ECDSA for authentication. Please don't use
this for anything important!!

The server has a list of trusted public keys, the client the public key of the server it trusts.

When connecting a new session, the client uses an ephemeral ECDH key signed by the client's long-term ECDSA key.
The server enforces that only one ephemeral ECDH key can be in use for each client key.

Handshake:
* Client sends it's pubkey and epehemeral pubkey, and sign the ephemeral pubkey and sends that.
* The client computes a shared secret to use as an AES128 key between the ephemeral ECDH key and the
  server's public key.
* If the server trusts the client's ECDSA key it computes the same shared secret using ECDH
* The server encrypts a random string using the shared key and sends it to the client.
* The client must decrypt and sign the plain text version of the string.
* The server verifies this final exchange and trusts the client.

"""

import os
import binascii
import identity
import hashlib
import pyaes
import uuid

KDFS = [
    "NULLAES128sha256str"
]
DEFAULT_KDF = "NULLAES128sha256str"


def aes_encrypt_str(key, plaintext):
    """
    Encrypt a string with AES.
    :param key:
    :param plaintext:
    :return:
    """
    iv = os.urandom(16)
    encrypter = pyaes.Encrypter(pyaes.AESModeOfOperationCBC(key, iv))
    ctext = encrypter.feed(plaintext)
    ctext += encrypter.feed()
    return binascii.hexlify(ctext), binascii.hexlify(iv)


def aes_decrypt_str(key, iv, ciphertext):
    """
    Decrypt a string with AES
    :param key:
    :param iv:
    :param ciphertext:
    :return:
    """
    iv = binascii.unhexlify(iv)
    ciphertext = binascii.unhexlify(ciphertext)
    decrypter = pyaes.Decrypter(pyaes.AESModeOfOperationCBC(key, iv))
    ptext = decrypter.feed(ciphertext)
    ptext += decrypter.feed()
    return ptext


def derive_key(kdf, shared):
    """
    Derive our secret key
    :param kdf:
    :param shared: shared secret ecpoints
    :return:
{'fraction_non_alphanumeric': 0.06952264381884946, 'fraction_numerical': 0.00832313341493268, 'mean_word_length': 3.6804123711340204, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1012330', 'n_tokens_mistral': 1373, 'n_tokens_neox': 1273, 'n_words': 517}