Example #1
0
def encrypt(message: bytes, pk_receiver: EncryptionPublicKey) -> bytes:
    """
    Encrypts a string message under a ec25519 public key by using a custom
    dhaes-based scheme.  See: https://eprint.iacr.org/1999/007
    """
    assert \
        len(message) == NOTE_LENGTH_BYTES, \
        f"expected message length {NOTE_LENGTH_BYTES}, saw {len(message)}"

    # Generate ephemeral keypair
    eph_keypair = generate_encryption_keypair()

    # Compute shared secret and eph key
    shared_key = _exchange(eph_keypair.k_sk, pk_receiver)
    pk_sender_bytes = encode_encryption_public_key(eph_keypair.k_pk)

    # Generate key material
    sym_key, mac_key = _kdf(pk_sender_bytes, shared_key)

    # Generate symmetric ciphertext
    # Chacha encryption
    algorithm = algorithms.ChaCha20(sym_key, _SYM_NONCE_VALUE)
    cipher = Cipher(algorithm, mode=None, backend=default_backend())
    encryptor = cipher.encryptor()
    sym_ciphertext = encryptor.update(message)

    # Generate mac
    mac = poly1305.Poly1305(mac_key)
    mac.update(sym_ciphertext)
    tag = mac.finalize()

    # Arrange ciphertext
    return pk_sender_bytes + sym_ciphertext + tag
Example #2
0
def generate_poly1305(key, nonce_or_iv):
    p = poly1305.Poly1305(key)

    def do_computation(msg: bytes):
        p.update(msg)
        # p.finalize()

    return do_computation
Example #3
0
def decrypt(encrypted_message: bytes,
            sk_receiver: EncryptionSecretKey) -> bytes:
    """
    Decrypts a NOTE_LENGTH-byte message by using valid ec25519 private key
    objects.  See: https://pynacl.readthedocs.io/en/stable/public/
    """
    assert \
        len(encrypted_message) == ENCRYPTED_NOTE_LENGTH_BYTES, \
        "encrypted_message byte-length must be: "+str(ENCRYPTED_NOTE_LENGTH_BYTES)

    assert(isinstance(sk_receiver, X25519PrivateKey)), \
        f"PrivateKey: {sk_receiver} ({type(sk_receiver)})"

    # Compute shared secret
    pk_sender_bytes = encrypted_message[:EC_PUBLIC_KEY_LENGTH_BYTES]
    pk_sender = decode_encryption_public_key(pk_sender_bytes)
    shared_key = _exchange(sk_receiver, pk_sender)

    # Generate key material and recover keys
    sym_key, mac_key = _kdf(pk_sender_bytes, shared_key)

    # ct_sym and mac
    ct_sym = encrypted_message[
        EC_PUBLIC_KEY_LENGTH_BYTES:EC_PUBLIC_KEY_LENGTH_BYTES +
        NOTE_LENGTH_BYTES]
    tag = encrypted_message[EC_PUBLIC_KEY_LENGTH_BYTES +
                            NOTE_LENGTH_BYTES:EC_PUBLIC_KEY_LENGTH_BYTES +
                            NOTE_LENGTH_BYTES + _TAG_LENGTH_BYTES]

    # Verify the mac
    mac = poly1305.Poly1305(mac_key)
    mac.update(ct_sym)
    mac.verify(tag)

    # Decrypt sym ciphertext
    algorithm = algorithms.ChaCha20(sym_key, _SYM_NONCE_VALUE)
    cipher = Cipher(algorithm, mode=None, backend=default_backend())
    decryptor = cipher.decryptor()
    message = decryptor.update(ct_sym)

    return message