U
    ֫[(                     @   s   d dl mZmZmZ d dlmZ d dlmZm	Z	 d dl
mZ e	 Ze	 Ze	 Ze	 Ze	 Ze	 Ze	 Ze	 Ze	 Zdd ZG dd deZ d	d
 Z!defddZ"dd Z#dddZ$dd Z%dS )    )absolute_importdivisionprint_function)
exceptions)ffilib)ensurec                  C   s(   t dt} t|  t | dd S )zd
    Generate a key for use with
    :func:`.crypto_secretstream_xchacha20poly1305_init_push`.

    unsigned char[]N)r   new.crypto_secretstream_xchacha20poly1305_KEYBYTESr   ,crypto_secretstream_xchacha20poly1305_keygenbuffer)Zkeybuf r   C/usr/lib/python3/dist-packages/nacl/bindings/crypto_secretstream.pyr   ,   s    
r   c                   @   s"   e Zd ZdZdddgZdd ZdS )+crypto_secretstream_xchacha20poly1305_statezN
    An object wrapping the crypto_secretstream_xchacha20poly1305 state.

    statebufrawbuftagbufc                 C   s   t dt| _d| _d| _dS )z! Initialize a clean state object.r	   N)r   r
   0crypto_secretstream_xchacha20poly1305_STATEBYTESr   r   r   )selfr   r   r   __init__A   s    z4crypto_secretstream_xchacha20poly1305_state.__init__N)__name__
__module____qualname____doc__	__slots__r   r   r   r   r   r   :   s   
r   c                 C   s   t t| tdtjd t t|tdtjd t t|tkdtjd t	
dt}t| j||}t |dkdtjd t	|dd S )	a\  
    Initialize a crypto_secretstream_xchacha20poly1305 encryption buffer.

    :param state: a secretstream state object
    :type state: crypto_secretstream_xchacha20poly1305_state
    :param key: must be
                :data:`.crypto_secretstream_xchacha20poly1305_KEYBYTES` long
    :type key: bytes
    :return: header
    :rtype: bytes

    BState must be a crypto_secretstream_xchacha20poly1305_state objectZraisingKey must be a bytes sequenceInvalid key lengthzunsigned char []r   Unexpected failureN)r   
isinstancer   exc	TypeErrorbyteslenr   
ValueErrorr   r
   1crypto_secretstream_xchacha20poly1305_HEADERBYTESr   /crypto_secretstream_xchacha20poly1305_init_pushr   RuntimeErrorr   )statekeyZ	headerbufrcr   r   r   r(   L   s4    
  r(   Nc              
   C   s   t t| tdtjd t t|tdtjd t t|tkdtjd t |dkpVt|tdtjd t|t	 }| j
dkst| j
|k rtd|| _
|dkrtj}d}nt|}t| j| j
tj|t||||}t |dkd	tjd t| j
|dd S )
a  
    Add an encrypted message to the secret stream.

    :param state: a secretstream state object
    :type state: crypto_secretstream_xchacha20poly1305_state
    :param m: the message to encrypt, the maximum length of an individual
              message is
              :data:`.crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX`.
    :type m: bytes
    :param ad: additional data to include in the authentication tag
    :type ad: bytes or None
    :param tag: the message tag, usually
                :data:`.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE` or
                :data:`.crypto_secretstream_xchacha20poly1305_TAG_FINAL`.
    :type tag: int
    :return: ciphertext
    :rtype: bytes

    r   r   zMessage is not byteszMessage is too longN%Additional data must be bytes or Noner	   r   r    )r   r!   r   r"   r#   r$   r%   6crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAXr&   ,crypto_secretstream_xchacha20poly1305_ABYTESr   r   r
   NULLr   *crypto_secretstream_xchacha20poly1305_pushr   r)   r   )r*   madtagZclenadlenr,   r   r   r   r1   u   sF    
   r1   c                 C   s   t t| tdtjd t t|tdtjd t t|tkdtjd t t|tdtjd t t|t	kdtjd | j
dkrtd| _
t| j||}t |d	kd
tjd dS )a  
    Initialize a crypto_secretstream_xchacha20poly1305 decryption buffer.

    :param state: a secretstream state object
    :type state: crypto_secretstream_xchacha20poly1305_state
    :param header: must be
                :data:`.crypto_secretstream_xchacha20poly1305_HEADERBYTES` long
    :type header: bytes
    :param key: must be
                :data:`.crypto_secretstream_xchacha20poly1305_KEYBYTES` long
    :type key: bytes

    r   r   zHeader must be a bytes sequencezInvalid header lengthr   r   Nzunsigned char *r   r    )r   r!   r   r"   r#   r$   r%   r'   r&   r   r   r   r
   r   /crypto_secretstream_xchacha20poly1305_init_pullr   r)   )r*   headerr+   r,   r   r   r   r6      sB    


  r6   c              
   C   s>  t t| tdtjd t | jdk	dtjd t t|tdtjd t t|t	kdtjd t t|t
t	 kdtjd t |dkpt|tdtjd t|t	 }| jdkst| j|k rtd	|| _|dkrtj}d
}nt|}t| j| jtj| j|t|||}t |d
kdtjd t| j|dd t| jd
 fS )aM  
    Read a decrypted message from the secret stream.

    :param state: a secretstream state object
    :type state: crypto_secretstream_xchacha20poly1305_state
    :param c: the ciphertext to decrypt, the maximum length of an individual
              ciphertext is
              :data:`.crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX` +
              :data:`.crypto_secretstream_xchacha20poly1305_ABYTES`.
    :type c: bytes
    :param ad: additional data to include in the authentication tag
    :type ad: bytes or None
    :return: (message, tag)
    :rtype: (bytes, int)

    r   r   NzOState must be initialized using crypto_secretstream_xchacha20poly1305_init_pullzCiphertext is not byteszCiphertext is too shortzCiphertext is too longr-   r	   r   r    )r   r!   r   r"   r#   r   r&   r$   r%   r/   r.   r   r   r
   r0   r   *crypto_secretstream_xchacha20poly1305_pullr   r)   r   int)r*   cr3   Zmlenr5   r,   r   r   r   r8      sj    
   r8   c                 C   s&   t t| tdtjd t| j dS )a  
    Explicitly change the encryption key in the stream.

    Normally the stream is re-keyed as needed or an explicit ``tag`` of
    :data:`.crypto_secretstream_xchacha20poly1305_TAG_REKEY` is added to a
    message to ensure forward secrecy, but this method can be used instead
    if the re-keying is controlled without adding the tag.

    :param state: a secretstream state object
    :type state: crypto_secretstream_xchacha20poly1305_state

    r   r   N)r   r!   r   r"   r#   r   +crypto_secretstream_xchacha20poly1305_rekeyr   )r*   r   r   r   r;   1  s    r;   )N)&Z
__future__r   r   r   Znaclr   r"   Znacl._sodiumr   r   Znacl.exceptionsr   Z,crypto_secretstream_xchacha20poly1305_abytesr/   Z1crypto_secretstream_xchacha20poly1305_headerbytesr'   Z.crypto_secretstream_xchacha20poly1305_keybytesr   Z6crypto_secretstream_xchacha20poly1305_messagebytes_maxr.   Z0crypto_secretstream_xchacha20poly1305_statebytesr   Z1crypto_secretstream_xchacha20poly1305_tag_messageZ1crypto_secretstream_xchacha20poly1305_TAG_MESSAGEZ.crypto_secretstream_xchacha20poly1305_tag_pushZ.crypto_secretstream_xchacha20poly1305_TAG_PUSHZ/crypto_secretstream_xchacha20poly1305_tag_rekeyZ/crypto_secretstream_xchacha20poly1305_TAG_REKEYZ/crypto_secretstream_xchacha20poly1305_tag_finalZ/crypto_secretstream_xchacha20poly1305_TAG_FINALr   objectr   r(   r1   r6   r8   r;   r   r   r   r   <module>   s<   ,
@0
L