# 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
    .. note:: See tor-spec Section 5.1.4 for more information.

    :returns: **str** raw byte string for this *onion skin*
    '''
    ret = ntorstate.relay_identity
    ret += ntorstate.relay_ntor_onion_key
    ret += bytes(ntorstate.public_key)
    return ret


def deriveRelayCrypto(ntorstate, cell):
    '''Derive shared key material for this ntor handshake; create and
    return actual cipher and hash instances inside a RelayCrypto object.

    .. note:: See tor-spec Section 5.1.4, 5.2.2 for more details.

    :param cell cell: Created2 cell or Extended2 cell used to derive
        shared keys
    :returns: **oppy.crypto.relaycrypto.RelayCrypto** object initialized
        with the derived key material.
    '''
    is_bad = False
    hdata = cell.hdata

    relay_pubkey = cell.hdata[:CURVE25519_PUBKEY_LEN]
    AUTH = hdata[CURVE25519_PUBKEY_LEN:CURVE25519_PUBKEY_LEN+DIGEST_LEN]

    secret_input, bad = _buildSecretInput(ntorstate, relay_pubkey)
    is_bad |= bad


# 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

    .. note:: See tor-spec Section 5.1.4 for more information.

    :returns: **str** raw byte string for this *onion skin*
    '''
    ret = ntorstate.relay_identity
    ret += ntorstate.relay_ntor_onion_key
    ret += bytes(ntorstate.public_key)
    return ret


def deriveRelayCrypto(ntorstate, cell):
    '''Derive shared key material for this ntor handshake; create and
    return actual cipher and hash instances inside a RelayCrypto object.

    .. note:: See tor-spec Section 5.1.4, 5.2.2 for more details.

    :param cell cell: Created2 cell or Extended2 cell used to derive
        shared keys
    :returns: **oppy.crypto.relaycrypto.RelayCrypto** object initialized
        with the derived key material.
    '''
    is_bad = False
    hdata = cell.hdata

    relay_pubkey = cell.hdata[:CURVE25519_PUBKEY_LEN]
    AUTH = hdata[CURVE25519_PUBKEY_LEN:CURVE25519_PUBKEY_LEN+DIGEST_LEN]

    secret_input, bad = _buildSecretInput(ntorstate, relay_pubkey)
    is_bad |= bad


    verify = util.makeHMACSHA256(msg=secret_input, key=T_VERIFY)