:- initialization(main, main). :- use_module(library(http/json)). :- use_module(binchunking). :- use_module(chacha20). :- use_module(chacha20_poly1305). :- use_module(poly1305). :- use_module(types). :- use_module(xchacha20_poly1305). test :- test_binchunking, test_chacha20, test_chacha20_poly1305, test_poly1305, test_xchacha20_poly1305. main([Key, Command, Input, Output]) :- processor(Command, Processor), !, test, json_read_file(Key, KeyValue), json_read_file(Input, InputValue), call(Processor, KeyValue, InputValue, OutputValue), !, json_write_file(Output, OutputValue). json_read_file(Fname, Value) :- open(Fname, read, Stream), json_read_dict(Stream, Value), close(Stream). json_write_file(Fname, Value) :- open(Fname, write, Stream), json_write_dict(Stream, Value), close(Stream). processor('-e', encrypt). processor('-d', decrypt). nonce(Nonce) :- crypto_n_random_bytes(24, Nonce). encrypt(_{key: Key}, _{aad: Aad, message: Plaintext}, Out) :- nonce(NonceBytes), string_bytes(Key, KeyBytes, utf8), assertion(is_xchacha20_key(KeyBytes)), string_bytes(Aad, AadBytes, utf8), string_bytes(Plaintext, PlaintextBytes, utf8), xchacha20_poly1305_encrypt( AadBytes, KeyBytes, NonceBytes, PlaintextBytes, CiphertextBytes, TagBytes ), hex_bytes(Nonce, NonceBytes), hex_bytes(Ciphertext, CiphertextBytes), hex_bytes(Tag, TagBytes), Out = _{ nonce: Nonce, aad: Aad, ciphertext: Ciphertext, tag: Tag }. decrypt(_{key: Key}, _{nonce: Nonce, aad: Aad, ciphertext: Ciphertext, tag: Tag}, Out) :- string_bytes(Key, KeyBytes, utf8), assertion(is_chacha20_key(KeyBytes)), string_bytes(Aad, AadBytes, utf8), hex_bytes(Nonce, NonceBytes), hex_bytes(Ciphertext, CiphertextBytes), hex_bytes(Tag, TagBytes), xchacha20_poly1305_decrypt( AadBytes, KeyBytes, NonceBytes, PlaintextBytes, CiphertextBytes, TagBytes ), string_bytes(Plaintext, PlaintextBytes, utf8), Out = _{ aad: Aad, message: Plaintext }.