From a131c93a144eb4f2583e1af36642066488669ae2 Mon Sep 17 00:00:00 2001 From: Markus Triska Date: Fri, 8 May 2020 21:58:56 +0200 Subject: [PATCH] ADDED: Initial version of library(crypto). --- src/prolog/lib/crypto.pl | 72 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/prolog/lib/crypto.pl diff --git a/src/prolog/lib/crypto.pl b/src/prolog/lib/crypto.pl new file mode 100644 index 00000000..c91f7de1 --- /dev/null +++ b/src/prolog/lib/crypto.pl @@ -0,0 +1,72 @@ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Written May 2020 by Markus Triska (triska@metalevel.at) + Part of Scryer Prolog. + + Predicates for cryptographic applications. + + This library assumes that the Prolog flag double_quotes is set to chars. + In Scryer Prolog, lists of characters are very efficiently represented, + and strings have the advantage that the atom table remains unmodified. + + Especially for cryptographic applications, it as an advantage that + using strings leaves little trace of what was processed in the system, +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +:- module(crypto, [hex_bytes/2]). + +:- use_module(library(error)). +:- use_module(library(lists)). +:- use_module(library(between)). +:- use_module(library(dcgs)). + +% hex_bytes(?Hex, ?Bytes) is det. +% +% Relation between a hexadecimal sequence and a list of bytes. Hex +% is a string of hexadecimal numbers. Bytes is a list of *integers* +% between 0 and 255 that represent the sequence as a list of bytes. +% At least one of the arguments must be instantiated. +% +% Example: +% +% == +% ?- hex_bytes("501ACE", Bs). +% Bs = [80,26,206] +% ; false. +% == + +hex_bytes(Hs, Bytes) :- + ( ground(Hs) -> + must_be(list, Hs), + maplist(must_be(atom), Hs), + ( phrase(hex_bytes(Hs), Bytes) -> + true + ; domain_error(hex_encoding, Hs, hex_bytes/2) + ) + ; must_be(list, Bytes), + maplist(must_be(integer), Bytes), + ( member(B, Bytes), \+ between(0, 255, B) -> + type_error(byte, B, hex_bytes/2) + ; true + ), + phrase(bytes_hex(Bytes), Hs) + ). + +hex_bytes([]) --> []. +hex_bytes([H1,H2|Hs]) --> [Byte], + { char_hexval(H1, High), + char_hexval(H2, Low), + Byte is High*16 + Low }, + hex_bytes(Hs). + +bytes_hex([]) --> []. +bytes_hex([B|Bs]) --> [C0,C1], + { High is B>>4, + Low is B /\ 0xf, + char_hexval(C0, High), + char_hexval(C1, Low) + }, + bytes_hex(Bs). + +char_hexval(C, H) :- nth0(H, "0123456789abcdef", C), !. +char_hexval(C, H) :- nth0(H, "0123456789ABCDEF", C), !. + -- 2.54.0