("$write_term_to_chars", 7) => Some(SystemClauseType::WriteTermToChars),
("$scryer_prolog_version", 1) => Some(SystemClauseType::ScryerPrologVersion),
("$crypto_random_byte", 1) => Some(SystemClauseType::CryptoRandomByte),
- ("$crypto_data_hash", 3) => Some(SystemClauseType::CryptoDataHash),
- ("$crypto_data_hkdf", 6) => Some(SystemClauseType::CryptoDataHKDF),
+ ("$crypto_data_hash", 4) => Some(SystemClauseType::CryptoDataHash),
+ ("$crypto_data_hkdf", 7) => Some(SystemClauseType::CryptoDataHKDF),
("$crypto_password_hash", 4) => Some(SystemClauseType::CryptoPasswordHash),
- ("$crypto_data_encrypt", 5) => Some(SystemClauseType::CryptoDataEncrypt),
- ("$crypto_data_decrypt", 5) => Some(SystemClauseType::CryptoDataDecrypt),
+ ("$crypto_data_encrypt", 6) => Some(SystemClauseType::CryptoDataEncrypt),
+ ("$crypto_data_decrypt", 6) => Some(SystemClauseType::CryptoDataDecrypt),
("$crypto_curve_scalar_mult", 5) => Some(SystemClauseType::CryptoCurveScalarMult),
- ("$ed25519_sign", 3) => Some(SystemClauseType::Ed25519Sign),
- ("$ed25519_verify", 3) => Some(SystemClauseType::Ed25519Verify),
+ ("$ed25519_sign", 5) => Some(SystemClauseType::Ed25519Sign),
+ ("$ed25519_verify", 5) => Some(SystemClauseType::Ed25519Verify),
("$ed25519_new_keypair", 1) => Some(SystemClauseType::Ed25519NewKeyPair),
- ("$ed25519_keypair_public_key", 2) => Some(SystemClauseType::Ed25519KeyPairPublicKey),
+ ("$ed25519_keypair_public_key", 3) => Some(SystemClauseType::Ed25519KeyPairPublicKey),
("$load_html", 3) => Some(SystemClauseType::LoadHTML),
("$load_xml", 3) => Some(SystemClauseType::LoadXML),
("$getenv", 2) => Some(SystemClauseType::GetEnv),
hex_bytes([H1,H2|Hs]) --> [Byte],
{ char_hexval(H1, High),
char_hexval(H2, Low),
- Byte is High*16 + Low },
+ Byte #= High*16 + Low },
hex_bytes(Hs).
bytes_hex([]) --> [].
bytes_hex([B|Bs]) --> [C0,C1],
- { High is B>>4,
- Low is B /\ 0xf,
+ { High #= B>>4,
+ Low #= B /\ 0xf,
char_hexval(C0, High),
char_hexval(C1, Low)
},
).
+must_be_byte_chars(Chars, Context) :-
+ must_be(list, Chars),
+ ( member(Char, Chars),
+ char_code(Char, Code),
+ \+ between(0, 255, Code) ->
+ domain_error(byte_char, Char, Context)
+ ; true
+ ).
+
+
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cryptographically secure random numbers
=======================================
crypto_data_hash(Data0, Hash, Options0) :-
must_be(list, Options0),
- options_data_bytes(Options0, Data0, Data),
+ options_data_chars(Options0, Data0, Data, Encoding),
functor_hash_options(algorithm, A, Options0, _),
( hash_algorithm(A) -> true
; domain_error(hash_algorithm, A, crypto_data_hash/3)
),
- '$crypto_data_hash'(Data, HashBytes, A),
+ '$crypto_data_hash'(Data, Encoding, HashBytes, A),
hex_bytes(Hash, HashBytes).
-options_data_bytes(Options, Data, Bytes) :-
+options_data_chars(Options, Data, Chars, Encoding) :-
option(encoding(Encoding), Options, utf8),
must_be(atom, Encoding),
- encoding_bytes(Encoding, Data, Bytes).
+ encoding_chars(Encoding, Data, Chars).
default_hash(sha256).
),
must_be(integer, L),
L >= 0,
- options_data_bytes(Options, Data0, Data),
+ options_data_chars(Options, Data0, Data, Encoding),
option(salt(SaltBytes), Options, []),
must_be_bytes(SaltBytes, crypto_data_hkdf/4),
option(info(Info0), Options, []),
chars_bytes_(Info0, Info, crypto_data_hkdf/4),
- '$crypto_data_hkdf'(Data, SaltBytes, Info, Algorithm, L, Bytes).
+ '$crypto_data_hkdf'(Data, Encoding, SaltBytes, Info, Algorithm, L, Bytes).
hkdf_algorithm(sha256).
hkdf_algorithm(sha384).
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
crypto_data_encrypt(PlainText0, Algorithm, Key, IV, CipherText, Options) :-
- options_data_bytes(Options, PlainText0, PlainText),
+ options_data_chars(Options, PlainText0, PlainText, Encoding),
option(tag(Tag), Options, _),
( nonvar(Tag) ->
must_be_bytes(Tag, crypto_data_encrypt/6)
( Algorithm = 'chacha20-poly1305' -> true
; domain_error('chacha20-poly1305', Algorithm, crypto_data_encrypt/6)
),
- '$crypto_data_encrypt'(PlainText, Key, IV, Tag, CipherText).
+ '$crypto_data_encrypt'(PlainText, Encoding, Key, IV, Tag, CipherText).
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
crypto_data_decrypt(+CipherText,
must_be(atom, Encoding),
member(Encoding, [utf8,octet]),
must_be(list, CipherText0),
- encoding_bytes(octet, CipherText0, CipherText1),
- append(CipherText1, Tag, CipherText),
+ encoding_chars(octet, CipherText0, CipherText1),
+ maplist(char_code, TagChars, Tag),
+ append(CipherText1, TagChars, CipherText),
( Algorithm = 'chacha20-poly1305' -> true
; domain_error('chacha20-poly1305', Algorithm, crypto_data_decrypt/6)
),
- '$crypto_data_decrypt'(CipherText, Key, IV, Encoding, PlainText).
+ '$crypto_data_decrypt'(CipherText, octet, Key, IV, Encoding, PlainText).
+
-encoding_bytes(octet, Bs0, Bs) :-
- must_be(list, Bs0),
- ( maplist(integer, Bs0) ->
- Bs0 = Bs
- ; maplist(char_code, Bs0, Bs)
+encoding_chars(octet, Bs, Cs) :-
+ must_be(list, Bs),
+ ( maplist(integer, Bs) ->
+ maplist(char_code, Cs, Bs)
+ ; Bs = Cs
),
- must_be_bytes(Bs, crypto_encoding).
-encoding_bytes(utf8, Cs, Bs) :-
+ must_be_byte_chars(Cs, crypto_encoding).
+encoding_chars(utf8, Cs, Cs) :-
must_be(list, Cs),
- ( maplist(atom, Cs) ->
- chars_bytes_(Cs, Bs, crypto_encoding)
- ; domain_error(encryption_encoding, Cs, crypto)
- ).
+ maplist(must_be(character), Cs).
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Digital signatures with Ed25519
ed25519_new_keypair(Pair) :-
'$ed25519_new_keypair'(Pair).
-ed25519_keypair_public_key(Pair0, PublicKey) :-
- encoding_bytes(octet, Pair0, Pair),
- '$ed25519_keypair_public_key'(Pair, PublicKey).
+ed25519_keypair_public_key(Pair, PublicKey) :-
+ must_be_byte_chars(Pair, ed25519_keypair_public_key),
+ '$ed25519_keypair_public_key'(Pair, octet, PublicKey).
-ed25519_sign(Key0, Data0, Signature, Options) :-
- options_data_bytes(Options, Data0, Data),
- encoding_bytes(octet, Key0, Key),
- '$ed25519_sign'(Key, Data, Signature0),
+ed25519_sign(Key, Data0, Signature, Options) :-
+ must_be_byte_chars(Key, ed25519_sign),
+ options_data_chars(Options, Data0, Data, Encoding),
+ '$ed25519_sign'(Key, octet, Data, Encoding, Signature0),
hex_bytes(Signature, Signature0).
-ed25519_verify(Key0, Data0, Signature0, Options) :-
- options_data_bytes(Options, Data0, Data),
- encoding_bytes(octet, Key0, Key),
+ed25519_verify(Key, Data0, Signature0, Options) :-
+ must_be_byte_chars(Key, ed25519_verify),
+ options_data_chars(Options, Data0, Data, Encoding),
hex_bytes(Signature0, Signature),
- '$ed25519_verify'(Key, Data, Signature).
+ '$ed25519_verify'(Key, octet, Data, Encoding, Signature).
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Operations on Elliptic Curves
self.unify(arg, byte);
}
&SystemClauseType::CryptoDataHash => {
- let stub = MachineError::functor_stub(clause_name!("crypto_data_hash"), 3);
- let bytes = self.integers_to_bytevec(temp_v!(1), stub);
+ let bytes = self.string_encoding_bytes(1, 2);
- let algorithm = self[temp_v!(3)];
- let algorithm_str = match self.store(self.deref(algorithm)) {
+ let algorithm_str = match self.store(self.deref(self[temp_v!(4)])) {
Addr::Con(h) if self.heap.atom_at(h) => {
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
atom.as_str()
}
};
- self.unify(self[temp_v!(2)], ints_list);
+ self.unify(self[temp_v!(3)], ints_list);
}
&SystemClauseType::CryptoDataHKDF => {
+ let data = self.string_encoding_bytes(1, 2);
let stub1 = MachineError::functor_stub(clause_name!("crypto_data_hkdf"), 4);
- let data = self.integers_to_bytevec(temp_v!(1), stub1);
+ let salt = self.integers_to_bytevec(temp_v!(3), stub1);
let stub2 = MachineError::functor_stub(clause_name!("crypto_data_hkdf"), 4);
- let salt = self.integers_to_bytevec(temp_v!(2), stub2);
- let stub3 = MachineError::functor_stub(clause_name!("crypto_data_hkdf"), 4);
- let info = self.integers_to_bytevec(temp_v!(3), stub3);
+ let info = self.integers_to_bytevec(temp_v!(4), stub2);
- let algorithm = match self.store(self.deref(self[temp_v!(4)])) {
+ let algorithm = match self.store(self.deref(self[temp_v!(5)])) {
Addr::Con(h) if self.heap.atom_at(h) => {
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
atom.as_str()
};
let length =
- match Number::try_from((self[temp_v!(5)], &self.heap)) {
+ match Number::try_from((self[temp_v!(6)], &self.heap)) {
Ok(Number::Fixnum(n)) => {
usize::try_from(n).unwrap()
}
Addr::HeapCell(self.heap.to_list(bytes.iter().map(|b| HeapCellValue::from(Addr::Fixnum(*b as isize)))))
};
- self.unify(self[temp_v!(6)], ints_list);
+ self.unify(self[temp_v!(7)], ints_list);
}
&SystemClauseType::CryptoPasswordHash => {
let stub1 = MachineError::functor_stub(clause_name!("crypto_password_hash"), 3);
self.unify(self[temp_v!(4)], ints_list);
}
&SystemClauseType::CryptoDataEncrypt => {
- let stub1 = MachineError::functor_stub(clause_name!("crypto_data_encrypt"), 6);
- let data = self.integers_to_bytevec(temp_v!(1), stub1);
+ let data = self.string_encoding_bytes(1, 2);
let stub2 = MachineError::functor_stub(clause_name!("crypto_data_encrypt"), 6);
- let key = self.integers_to_bytevec(temp_v!(2), stub2);
+ let key = self.integers_to_bytevec(temp_v!(3), stub2);
let stub3 = MachineError::functor_stub(clause_name!("crypto_data_encrypt"), 6);
- let iv = self.integers_to_bytevec(temp_v!(3), stub3);
+ let iv = self.integers_to_bytevec(temp_v!(4), stub3);
let unbound_key = aead::UnboundKey::new(&aead::CHACHA20_POLY1305, &key).unwrap();
let nonce = aead::Nonce::try_assume_unique_for_key(&iv).unwrap();
self.heap.put_complete_string(&buffer)
};
- self.unify(self[temp_v!(4)], tag_list);
- self.unify(self[temp_v!(5)], complete_string);
+ self.unify(self[temp_v!(5)], tag_list);
+ self.unify(self[temp_v!(6)], complete_string);
}
&SystemClauseType::CryptoDataDecrypt => {
+ let data = self.string_encoding_bytes(1, 2);
let stub1 = MachineError::functor_stub(clause_name!("crypto_data_decrypt"), 6);
- let data = self.integers_to_bytevec(temp_v!(1), stub1);
+ let key = self.integers_to_bytevec(temp_v!(3), stub1);
let stub2 = MachineError::functor_stub(clause_name!("crypto_data_decrypt"), 6);
- let key = self.integers_to_bytevec(temp_v!(2), stub2);
- let stub3 = MachineError::functor_stub(clause_name!("crypto_data_decrypt"), 6);
- let iv = self.integers_to_bytevec(temp_v!(3), stub3);
+ let iv = self.integers_to_bytevec(temp_v!(4), stub2);
- let encoding = match self.store(self.deref(self[temp_v!(4)])) {
+ let encoding = match self.store(self.deref(self[temp_v!(5)])) {
Addr::Con(h) if self.heap.atom_at(h) => {
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
atom.as_str()
self.heap.put_complete_string(&buffer)
};
- self.unify(self[temp_v!(5)], complete_string);
+ self.unify(self[temp_v!(6)], complete_string);
}
&SystemClauseType::CryptoCurveScalarMult => {
let curve = match self.store(self.deref(self[temp_v!(1)])) {
self.unify(self[temp_v!(1)], complete_string);
}
&SystemClauseType::Ed25519KeyPairPublicKey => {
- let stub1 = MachineError::functor_stub(clause_name!("ed25519_keypair_public_key"), 2);
- let bytes = self.integers_to_bytevec(temp_v!(1), stub1);
+ let bytes = self.string_encoding_bytes(1, 2);
let key_pair = match signature::Ed25519KeyPair::from_pkcs8(&bytes) {
Ok(kp) => { kp }
self.heap.put_complete_string(&buffer)
};
- self.unify(self[temp_v!(2)], complete_string);
+ self.unify(self[temp_v!(3)], complete_string);
}
&SystemClauseType::Ed25519Sign => {
- let stub1 = MachineError::functor_stub(clause_name!("ed25519_sign"), 4);
- let key = self.integers_to_bytevec(temp_v!(1), stub1);
- let stub2 = MachineError::functor_stub(clause_name!("ed25519_sign"), 4);
- let data = self.integers_to_bytevec(temp_v!(2), stub2);
+ let key = self.string_encoding_bytes(1, 2);
+ let data = self.string_encoding_bytes(3, 4);
let key_pair = match signature::Ed25519KeyPair::from_pkcs8(&key) {
Ok(kp) => { kp }
let sig_list =
Addr::HeapCell(self.heap.to_list(sig.as_ref().iter().map(|b| HeapCellValue::from(Addr::Fixnum(*b as isize)))));
- self.unify(self[temp_v!(3)], sig_list);
+ self.unify(self[temp_v!(5)], sig_list);
}
&SystemClauseType::Ed25519Verify => {
- let stub1 = MachineError::functor_stub(clause_name!("ed25519_verify"), 4);
- let key = self.integers_to_bytevec(temp_v!(1), stub1);
- let stub2 = MachineError::functor_stub(clause_name!("ed25519_verify"), 4);
- let data = self.integers_to_bytevec(temp_v!(2), stub2);
- let stub3 = MachineError::functor_stub(clause_name!("ed25519_verify"), 4);
- let signature = self.integers_to_bytevec(temp_v!(3), stub3);
+ let key = self.string_encoding_bytes(1, 2);
+ let data = self.string_encoding_bytes(3, 4);
+ let stub = MachineError::functor_stub(clause_name!("ed25519_verify"), 5);
+ let signature = self.integers_to_bytevec(temp_v!(5), stub);
let peer_public_key = signature::UnparsedPublicKey::new(&signature::ED25519, &key);
match peer_public_key.verify(&data, &signature) {
return_from_clause!(self.last_call, self)
}
+ pub(super)
+ fn string_encoding_bytes(
+ &mut self,
+ data_arg: usize,
+ encoding_arg: usize,
+ ) -> Vec<u8> {
+ let data = self.heap_pstr_iter(self[temp_v!(data_arg)]).to_string();
+
+ let encoding_str = match self.store(self.deref(self[temp_v!(encoding_arg)])) {
+ Addr::Con(h) if self.heap.atom_at(h) => {
+ if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
+ atom.as_str()
+ } else {
+ unreachable!()
+ }
+ }
+ _ => {
+ unreachable!()
+ }
+ };
+
+ match encoding_str {
+ "utf8" => { data.into_bytes() }
+ "octet" => {
+ let mut buf = vec![];
+ for c in data.chars() {
+ buf.push(c as u8);
+ }
+ buf
+ }
+ _ => { unreachable!() }
+ }
+ }
+
pub(super)
fn xml_node_to_term(
&mut self,