# Path: oppy/crypto/util.py
# class UnrecognizedCell(Exception):
# def constantStrEqual(str1, str2):
# def constantStrAllZero(s):
# def makeAES128CTRCipher(key, initial_value=0):
# def makeHMACSHA256(msg, key):
# def _makePayloadWithDigest(payload, digest=EMPTY_DIGEST):
# def encryptCell(cell, crypt_path, early=False):
# def _cellRecognized(payload, relay_crypto):
# def decryptCell(cell, crypt_path):
# def verifyCertSig(id_cert, cert_to_verify, algo='sha1'):
# def validCertTime(cert):
#     DIGEST_START = 5
#     DIGEST_END = 9
# 
# Path: oppy/util/tools.py
# def decodeMicrodescriptorIdentifier(microdescriptor):
#     ident = microdescriptor.identifier
#     short = 4-len(ident)%4
#     if short:
#         ident += '='*short
#     return base64.b64decode(ident).rstrip('=')


import base64
import hashlib
import hkdf
from collections import namedtuple
from nacl import bindings
from nacl.public import PrivateKey, PublicKey
from oppy.crypto import util
from oppy.util.tools import decodeMicrodescriptorIdentifier
.. warning:: NTorHandshakes do not safely erase/clear memory of private keys.

'''





PROTOID     = "ntor-curve25519-sha256-1"
T_MAC       = PROTOID + ":mac"
T_KEY       = PROTOID + ":key_extract"
T_VERIFY    = PROTOID + ":verify"
M_EXPAND    = PROTOID + ":key_expand"
SERVER_STR  = "Server"

CURVE25519_PUBKEY_LEN   = 32
DIGEST_LEN              = 20
KEY_LEN                 = 16


class KeyDerivationFailed(Exception):
    pass


class NTorState(namedtuple('NTorState',
    ('relay_identity', 'relay_ntor_onion_key', 'secret_key', 'public_key'))):

    __slots__ = ()

    def __new__(cls, microdescriptor):

# Path: oppy/crypto/util.py
# class UnrecognizedCell(Exception):
# def constantStrEqual(str1, str2):
# def constantStrAllZero(s):
# def makeAES128CTRCipher(key, initial_value=0):
# def makeHMACSHA256(msg, key):
# def _makePayloadWithDigest(payload, digest=EMPTY_DIGEST):
# def encryptCell(cell, crypt_path, early=False):
# def _cellRecognized(payload, relay_crypto):
# def decryptCell(cell, crypt_path):
# def verifyCertSig(id_cert, cert_to_verify, algo='sha1'):
# def validCertTime(cert):
#     DIGEST_START = 5
#     DIGEST_END = 9
# 
# Path: oppy/util/tools.py
# def decodeMicrodescriptorIdentifier(microdescriptor):
#     ident = microdescriptor.identifier
#     short = 4-len(ident)%4
#     if short:
#         ident += '='*short
#     return base64.b64decode(ident).rstrip('=')


# Path: oppy/crypto/ntor.py
import base64
import hashlib
import hkdf
from collections import namedtuple
from nacl import bindings
from nacl.public import PrivateKey, PublicKey
from oppy.crypto import util
from oppy.util.tools import decodeMicrodescriptorIdentifier

.. warning:: NTorHandshakes do not safely erase/clear memory of private keys.

'''





PROTOID     = "ntor-curve25519-sha256-1"
T_MAC       = PROTOID + ":mac"
T_KEY       = PROTOID + ":key_extract"
T_VERIFY    = PROTOID + ":verify"
M_EXPAND    = PROTOID + ":key_expand"
SERVER_STR  = "Server"

CURVE25519_PUBKEY_LEN   = 32
DIGEST_LEN              = 20
KEY_LEN                 = 16


class KeyDerivationFailed(Exception):
    pass


class NTorState(namedtuple('NTorState',
    ('relay_identity', 'relay_ntor_onion_key', 'secret_key', 'public_key'))):

    __slots__ = ()

    def __new__(cls, microdescriptor):

        relay_identity = decodeMicrodescriptorIdentifier(microdescriptor)