Merge pull request #626 from triska/compact_crypto
ENHANCED: library(crypto): Retain the compact representation of strings.
This commit is contained in:
@@ -445,10 +445,11 @@ The modules that ship with Scryer Prolog are also called
|
|||||||
* [`os`](src/lib/os.pl)
|
* [`os`](src/lib/os.pl)
|
||||||
Predicates for reasoning about environment variables.
|
Predicates for reasoning about environment variables.
|
||||||
* [`crypto`](src/lib/crypto.pl)
|
* [`crypto`](src/lib/crypto.pl)
|
||||||
Cryptographically secure random numbers and hashes, HMAC-based
|
Cryptographically secure random numbers and hashes, HMAC-based key
|
||||||
key derivation (HKDF), password-based key derivation (PBKDF2),
|
derivation (HKDF), password-based key derivation (PBKDF2),
|
||||||
public key signatures and signature verification with Ed25519,
|
public key signatures and signature verification with Ed25519,
|
||||||
authenticated encryption, and reasoning about elliptic curves.
|
authenticated symmetric encryption with ChaCha20-Poly1305, and
|
||||||
|
reasoning about elliptic curves.
|
||||||
|
|
||||||
To use predicates provided by the `lists` library, write:
|
To use predicates provided by the `lists` library, write:
|
||||||
|
|
||||||
|
|||||||
@@ -688,16 +688,16 @@ impl SystemClauseType {
|
|||||||
("$write_term_to_chars", 7) => Some(SystemClauseType::WriteTermToChars),
|
("$write_term_to_chars", 7) => Some(SystemClauseType::WriteTermToChars),
|
||||||
("$scryer_prolog_version", 1) => Some(SystemClauseType::ScryerPrologVersion),
|
("$scryer_prolog_version", 1) => Some(SystemClauseType::ScryerPrologVersion),
|
||||||
("$crypto_random_byte", 1) => Some(SystemClauseType::CryptoRandomByte),
|
("$crypto_random_byte", 1) => Some(SystemClauseType::CryptoRandomByte),
|
||||||
("$crypto_data_hash", 3) => Some(SystemClauseType::CryptoDataHash),
|
("$crypto_data_hash", 4) => Some(SystemClauseType::CryptoDataHash),
|
||||||
("$crypto_data_hkdf", 6) => Some(SystemClauseType::CryptoDataHKDF),
|
("$crypto_data_hkdf", 7) => Some(SystemClauseType::CryptoDataHKDF),
|
||||||
("$crypto_password_hash", 4) => Some(SystemClauseType::CryptoPasswordHash),
|
("$crypto_password_hash", 4) => Some(SystemClauseType::CryptoPasswordHash),
|
||||||
("$crypto_data_encrypt", 5) => Some(SystemClauseType::CryptoDataEncrypt),
|
("$crypto_data_encrypt", 6) => Some(SystemClauseType::CryptoDataEncrypt),
|
||||||
("$crypto_data_decrypt", 5) => Some(SystemClauseType::CryptoDataDecrypt),
|
("$crypto_data_decrypt", 6) => Some(SystemClauseType::CryptoDataDecrypt),
|
||||||
("$crypto_curve_scalar_mult", 5) => Some(SystemClauseType::CryptoCurveScalarMult),
|
("$crypto_curve_scalar_mult", 5) => Some(SystemClauseType::CryptoCurveScalarMult),
|
||||||
("$ed25519_sign", 3) => Some(SystemClauseType::Ed25519Sign),
|
("$ed25519_sign", 5) => Some(SystemClauseType::Ed25519Sign),
|
||||||
("$ed25519_verify", 3) => Some(SystemClauseType::Ed25519Verify),
|
("$ed25519_verify", 5) => Some(SystemClauseType::Ed25519Verify),
|
||||||
("$ed25519_new_keypair", 1) => Some(SystemClauseType::Ed25519NewKeyPair),
|
("$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_html", 3) => Some(SystemClauseType::LoadHTML),
|
||||||
("$load_xml", 3) => Some(SystemClauseType::LoadXML),
|
("$load_xml", 3) => Some(SystemClauseType::LoadXML),
|
||||||
("$getenv", 2) => Some(SystemClauseType::GetEnv),
|
("$getenv", 2) => Some(SystemClauseType::GetEnv),
|
||||||
|
|||||||
@@ -76,13 +76,13 @@ hex_bytes([]) --> [].
|
|||||||
hex_bytes([H1,H2|Hs]) --> [Byte],
|
hex_bytes([H1,H2|Hs]) --> [Byte],
|
||||||
{ char_hexval(H1, High),
|
{ char_hexval(H1, High),
|
||||||
char_hexval(H2, Low),
|
char_hexval(H2, Low),
|
||||||
Byte is High*16 + Low },
|
Byte #= High*16 + Low },
|
||||||
hex_bytes(Hs).
|
hex_bytes(Hs).
|
||||||
|
|
||||||
bytes_hex([]) --> [].
|
bytes_hex([]) --> [].
|
||||||
bytes_hex([B|Bs]) --> [C0,C1],
|
bytes_hex([B|Bs]) --> [C0,C1],
|
||||||
{ High is B>>4,
|
{ High #= B>>4,
|
||||||
Low is B /\ 0xf,
|
Low #= B /\ 0xf,
|
||||||
char_hexval(C0, High),
|
char_hexval(C0, High),
|
||||||
char_hexval(C1, Low)
|
char_hexval(C1, Low)
|
||||||
},
|
},
|
||||||
@@ -101,6 +101,16 @@ must_be_bytes(Bytes, Context) :-
|
|||||||
).
|
).
|
||||||
|
|
||||||
|
|
||||||
|
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
|
Cryptographically secure random numbers
|
||||||
=======================================
|
=======================================
|
||||||
@@ -191,18 +201,18 @@ crypto_random_byte(B) :- '$crypto_random_byte'(B).
|
|||||||
|
|
||||||
crypto_data_hash(Data0, Hash, Options0) :-
|
crypto_data_hash(Data0, Hash, Options0) :-
|
||||||
must_be(list, Options0),
|
must_be(list, Options0),
|
||||||
options_data_bytes(Options0, Data0, Data),
|
options_data_chars(Options0, Data0, Data, Encoding),
|
||||||
functor_hash_options(algorithm, A, Options0, _),
|
functor_hash_options(algorithm, A, Options0, _),
|
||||||
( hash_algorithm(A) -> true
|
( hash_algorithm(A) -> true
|
||||||
; domain_error(hash_algorithm, A, crypto_data_hash/3)
|
; 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).
|
hex_bytes(Hash, HashBytes).
|
||||||
|
|
||||||
options_data_bytes(Options, Data, Bytes) :-
|
options_data_chars(Options, Data, Chars, Encoding) :-
|
||||||
option(encoding(Encoding), Options, utf8),
|
option(encoding(Encoding), Options, utf8),
|
||||||
must_be(atom, Encoding),
|
must_be(atom, Encoding),
|
||||||
encoding_bytes(Encoding, Data, Bytes).
|
encoding_chars(Encoding, Data, Chars).
|
||||||
|
|
||||||
default_hash(sha256).
|
default_hash(sha256).
|
||||||
|
|
||||||
@@ -270,12 +280,12 @@ crypto_data_hkdf(Data0, L, Bytes, Options0) :-
|
|||||||
),
|
),
|
||||||
must_be(integer, L),
|
must_be(integer, L),
|
||||||
L >= 0,
|
L >= 0,
|
||||||
options_data_bytes(Options, Data0, Data),
|
options_data_chars(Options, Data0, Data, Encoding),
|
||||||
option(salt(SaltBytes), Options, []),
|
option(salt(SaltBytes), Options, []),
|
||||||
must_be_bytes(SaltBytes, crypto_data_hkdf/4),
|
must_be_bytes(SaltBytes, crypto_data_hkdf/4),
|
||||||
option(info(Info0), Options, []),
|
option(info(Info0), Options, []),
|
||||||
chars_bytes_(Info0, Info, crypto_data_hkdf/4),
|
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(sha256).
|
||||||
hkdf_algorithm(sha384).
|
hkdf_algorithm(sha384).
|
||||||
@@ -558,7 +568,7 @@ bytes_base64_([A,B,C|Ls]) --> [W,X,Y,Z],
|
|||||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||||
|
|
||||||
crypto_data_encrypt(PlainText0, Algorithm, Key, IV, CipherText, Options) :-
|
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, _),
|
option(tag(Tag), Options, _),
|
||||||
( nonvar(Tag) ->
|
( nonvar(Tag) ->
|
||||||
must_be_bytes(Tag, crypto_data_encrypt/6)
|
must_be_bytes(Tag, crypto_data_encrypt/6)
|
||||||
@@ -570,7 +580,7 @@ crypto_data_encrypt(PlainText0, Algorithm, Key, IV, CipherText, Options) :-
|
|||||||
( Algorithm = 'chacha20-poly1305' -> true
|
( Algorithm = 'chacha20-poly1305' -> true
|
||||||
; domain_error('chacha20-poly1305', Algorithm, crypto_data_encrypt/6)
|
; 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,
|
crypto_data_decrypt(+CipherText,
|
||||||
@@ -610,26 +620,25 @@ crypto_data_decrypt(CipherText0, Algorithm, Key, IV, PlainText, Options) :-
|
|||||||
must_be(atom, Encoding),
|
must_be(atom, Encoding),
|
||||||
member(Encoding, [utf8,octet]),
|
member(Encoding, [utf8,octet]),
|
||||||
must_be(list, CipherText0),
|
must_be(list, CipherText0),
|
||||||
encoding_bytes(octet, CipherText0, CipherText1),
|
encoding_chars(octet, CipherText0, CipherText1),
|
||||||
append(CipherText1, Tag, CipherText),
|
maplist(char_code, TagChars, Tag),
|
||||||
|
append(CipherText1, TagChars, CipherText),
|
||||||
( Algorithm = 'chacha20-poly1305' -> true
|
( Algorithm = 'chacha20-poly1305' -> true
|
||||||
; domain_error('chacha20-poly1305', Algorithm, crypto_data_decrypt/6)
|
; 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),
|
encoding_chars(octet, Bs, Cs) :-
|
||||||
( maplist(integer, Bs0) ->
|
must_be(list, Bs),
|
||||||
Bs0 = Bs
|
( maplist(integer, Bs) ->
|
||||||
; maplist(char_code, Bs0, Bs)
|
maplist(char_code, Cs, Bs)
|
||||||
|
; Bs = Cs
|
||||||
),
|
),
|
||||||
must_be_bytes(Bs, crypto_encoding).
|
must_be_byte_chars(Cs, crypto_encoding).
|
||||||
encoding_bytes(utf8, Cs, Bs) :-
|
encoding_chars(utf8, Cs, Cs) :-
|
||||||
must_be(list, Cs),
|
must_be(list, Cs),
|
||||||
( maplist(atom, Cs) ->
|
maplist(must_be(character), Cs).
|
||||||
chars_bytes_(Cs, Bs, crypto_encoding)
|
|
||||||
; domain_error(encryption_encoding, Cs, crypto)
|
|
||||||
).
|
|
||||||
|
|
||||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Digital signatures with Ed25519
|
Digital signatures with Ed25519
|
||||||
@@ -667,21 +676,21 @@ encoding_bytes(utf8, Cs, Bs) :-
|
|||||||
ed25519_new_keypair(Pair) :-
|
ed25519_new_keypair(Pair) :-
|
||||||
'$ed25519_new_keypair'(Pair).
|
'$ed25519_new_keypair'(Pair).
|
||||||
|
|
||||||
ed25519_keypair_public_key(Pair0, PublicKey) :-
|
ed25519_keypair_public_key(Pair, PublicKey) :-
|
||||||
encoding_bytes(octet, Pair0, Pair),
|
must_be_byte_chars(Pair, ed25519_keypair_public_key),
|
||||||
'$ed25519_keypair_public_key'(Pair, PublicKey).
|
'$ed25519_keypair_public_key'(Pair, octet, PublicKey).
|
||||||
|
|
||||||
ed25519_sign(Key0, Data0, Signature, Options) :-
|
ed25519_sign(Key, Data0, Signature, Options) :-
|
||||||
options_data_bytes(Options, Data0, Data),
|
must_be_byte_chars(Key, ed25519_sign),
|
||||||
encoding_bytes(octet, Key0, Key),
|
options_data_chars(Options, Data0, Data, Encoding),
|
||||||
'$ed25519_sign'(Key, Data, Signature0),
|
'$ed25519_sign'(Key, octet, Data, Encoding, Signature0),
|
||||||
hex_bytes(Signature, Signature0).
|
hex_bytes(Signature, Signature0).
|
||||||
|
|
||||||
ed25519_verify(Key0, Data0, Signature0, Options) :-
|
ed25519_verify(Key, Data0, Signature0, Options) :-
|
||||||
options_data_bytes(Options, Data0, Data),
|
must_be_byte_chars(Key, ed25519_verify),
|
||||||
encoding_bytes(octet, Key0, Key),
|
options_data_chars(Options, Data0, Data, Encoding),
|
||||||
hex_bytes(Signature0, Signature),
|
hex_bytes(Signature0, Signature),
|
||||||
'$ed25519_verify'(Key, Data, Signature).
|
'$ed25519_verify'(Key, octet, Data, Encoding, Signature).
|
||||||
|
|
||||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Operations on Elliptic Curves
|
Operations on Elliptic Curves
|
||||||
|
|||||||
@@ -5291,11 +5291,9 @@ impl MachineState {
|
|||||||
self.unify(arg, byte);
|
self.unify(arg, byte);
|
||||||
}
|
}
|
||||||
&SystemClauseType::CryptoDataHash => {
|
&SystemClauseType::CryptoDataHash => {
|
||||||
let stub = MachineError::functor_stub(clause_name!("crypto_data_hash"), 3);
|
let bytes = self.string_encoding_bytes(1, 2);
|
||||||
let bytes = self.integers_to_bytevec(temp_v!(1), stub);
|
|
||||||
|
|
||||||
let algorithm = self[temp_v!(3)];
|
let algorithm_str = match self.store(self.deref(self[temp_v!(4)])) {
|
||||||
let algorithm_str = match self.store(self.deref(algorithm)) {
|
|
||||||
Addr::Con(h) if self.heap.atom_at(h) => {
|
Addr::Con(h) if self.heap.atom_at(h) => {
|
||||||
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
|
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
|
||||||
atom.as_str()
|
atom.as_str()
|
||||||
@@ -5344,17 +5342,16 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.unify(self[temp_v!(2)], ints_list);
|
self.unify(self[temp_v!(3)], ints_list);
|
||||||
}
|
}
|
||||||
&SystemClauseType::CryptoDataHKDF => {
|
&SystemClauseType::CryptoDataHKDF => {
|
||||||
|
let data = self.string_encoding_bytes(1, 2);
|
||||||
let stub1 = MachineError::functor_stub(clause_name!("crypto_data_hkdf"), 4);
|
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 stub2 = MachineError::functor_stub(clause_name!("crypto_data_hkdf"), 4);
|
||||||
let salt = self.integers_to_bytevec(temp_v!(2), stub2);
|
let info = self.integers_to_bytevec(temp_v!(4), stub2);
|
||||||
let stub3 = MachineError::functor_stub(clause_name!("crypto_data_hkdf"), 4);
|
|
||||||
let info = self.integers_to_bytevec(temp_v!(3), stub3);
|
|
||||||
|
|
||||||
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) => {
|
Addr::Con(h) if self.heap.atom_at(h) => {
|
||||||
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
|
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
|
||||||
atom.as_str()
|
atom.as_str()
|
||||||
@@ -5368,7 +5365,7 @@ impl MachineState {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let length =
|
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)) => {
|
Ok(Number::Fixnum(n)) => {
|
||||||
usize::try_from(n).unwrap()
|
usize::try_from(n).unwrap()
|
||||||
}
|
}
|
||||||
@@ -5400,7 +5397,7 @@ impl MachineState {
|
|||||||
Addr::HeapCell(self.heap.to_list(bytes.iter().map(|b| HeapCellValue::from(Addr::Fixnum(*b as isize)))))
|
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 => {
|
&SystemClauseType::CryptoPasswordHash => {
|
||||||
let stub1 = MachineError::functor_stub(clause_name!("crypto_password_hash"), 3);
|
let stub1 = MachineError::functor_stub(clause_name!("crypto_password_hash"), 3);
|
||||||
@@ -5436,12 +5433,11 @@ impl MachineState {
|
|||||||
self.unify(self[temp_v!(4)], ints_list);
|
self.unify(self[temp_v!(4)], ints_list);
|
||||||
}
|
}
|
||||||
&SystemClauseType::CryptoDataEncrypt => {
|
&SystemClauseType::CryptoDataEncrypt => {
|
||||||
let stub1 = MachineError::functor_stub(clause_name!("crypto_data_encrypt"), 6);
|
let data = self.string_encoding_bytes(1, 2);
|
||||||
let data = self.integers_to_bytevec(temp_v!(1), stub1);
|
|
||||||
let stub2 = MachineError::functor_stub(clause_name!("crypto_data_encrypt"), 6);
|
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 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 unbound_key = aead::UnboundKey::new(&aead::CHACHA20_POLY1305, &key).unwrap();
|
||||||
let nonce = aead::Nonce::try_assume_unique_for_key(&iv).unwrap();
|
let nonce = aead::Nonce::try_assume_unique_for_key(&iv).unwrap();
|
||||||
@@ -5462,18 +5458,17 @@ impl MachineState {
|
|||||||
self.heap.put_complete_string(&buffer)
|
self.heap.put_complete_string(&buffer)
|
||||||
};
|
};
|
||||||
|
|
||||||
self.unify(self[temp_v!(4)], tag_list);
|
self.unify(self[temp_v!(5)], tag_list);
|
||||||
self.unify(self[temp_v!(5)], complete_string);
|
self.unify(self[temp_v!(6)], complete_string);
|
||||||
}
|
}
|
||||||
&SystemClauseType::CryptoDataDecrypt => {
|
&SystemClauseType::CryptoDataDecrypt => {
|
||||||
|
let data = self.string_encoding_bytes(1, 2);
|
||||||
let stub1 = MachineError::functor_stub(clause_name!("crypto_data_decrypt"), 6);
|
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 stub2 = MachineError::functor_stub(clause_name!("crypto_data_decrypt"), 6);
|
||||||
let key = self.integers_to_bytevec(temp_v!(2), stub2);
|
let iv = self.integers_to_bytevec(temp_v!(4), stub2);
|
||||||
let stub3 = MachineError::functor_stub(clause_name!("crypto_data_decrypt"), 6);
|
|
||||||
let iv = self.integers_to_bytevec(temp_v!(3), stub3);
|
|
||||||
|
|
||||||
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) => {
|
Addr::Con(h) if self.heap.atom_at(h) => {
|
||||||
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
|
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
|
||||||
atom.as_str()
|
atom.as_str()
|
||||||
@@ -5512,7 +5507,7 @@ impl MachineState {
|
|||||||
self.heap.put_complete_string(&buffer)
|
self.heap.put_complete_string(&buffer)
|
||||||
};
|
};
|
||||||
|
|
||||||
self.unify(self[temp_v!(5)], complete_string);
|
self.unify(self[temp_v!(6)], complete_string);
|
||||||
}
|
}
|
||||||
&SystemClauseType::CryptoCurveScalarMult => {
|
&SystemClauseType::CryptoCurveScalarMult => {
|
||||||
let curve = match self.store(self.deref(self[temp_v!(1)])) {
|
let curve = match self.store(self.deref(self[temp_v!(1)])) {
|
||||||
@@ -5573,8 +5568,7 @@ impl MachineState {
|
|||||||
self.unify(self[temp_v!(1)], complete_string);
|
self.unify(self[temp_v!(1)], complete_string);
|
||||||
}
|
}
|
||||||
&SystemClauseType::Ed25519KeyPairPublicKey => {
|
&SystemClauseType::Ed25519KeyPairPublicKey => {
|
||||||
let stub1 = MachineError::functor_stub(clause_name!("ed25519_keypair_public_key"), 2);
|
let bytes = self.string_encoding_bytes(1, 2);
|
||||||
let bytes = self.integers_to_bytevec(temp_v!(1), stub1);
|
|
||||||
|
|
||||||
let key_pair = match signature::Ed25519KeyPair::from_pkcs8(&bytes) {
|
let key_pair = match signature::Ed25519KeyPair::from_pkcs8(&bytes) {
|
||||||
Ok(kp) => { kp }
|
Ok(kp) => { kp }
|
||||||
@@ -5586,13 +5580,11 @@ impl MachineState {
|
|||||||
self.heap.put_complete_string(&buffer)
|
self.heap.put_complete_string(&buffer)
|
||||||
};
|
};
|
||||||
|
|
||||||
self.unify(self[temp_v!(2)], complete_string);
|
self.unify(self[temp_v!(3)], complete_string);
|
||||||
}
|
}
|
||||||
&SystemClauseType::Ed25519Sign => {
|
&SystemClauseType::Ed25519Sign => {
|
||||||
let stub1 = MachineError::functor_stub(clause_name!("ed25519_sign"), 4);
|
let key = self.string_encoding_bytes(1, 2);
|
||||||
let key = self.integers_to_bytevec(temp_v!(1), stub1);
|
let data = self.string_encoding_bytes(3, 4);
|
||||||
let stub2 = MachineError::functor_stub(clause_name!("ed25519_sign"), 4);
|
|
||||||
let data = self.integers_to_bytevec(temp_v!(2), stub2);
|
|
||||||
|
|
||||||
let key_pair = match signature::Ed25519KeyPair::from_pkcs8(&key) {
|
let key_pair = match signature::Ed25519KeyPair::from_pkcs8(&key) {
|
||||||
Ok(kp) => { kp }
|
Ok(kp) => { kp }
|
||||||
@@ -5604,15 +5596,13 @@ impl MachineState {
|
|||||||
let sig_list =
|
let sig_list =
|
||||||
Addr::HeapCell(self.heap.to_list(sig.as_ref().iter().map(|b| HeapCellValue::from(Addr::Fixnum(*b as isize)))));
|
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 => {
|
&SystemClauseType::Ed25519Verify => {
|
||||||
let stub1 = MachineError::functor_stub(clause_name!("ed25519_verify"), 4);
|
let key = self.string_encoding_bytes(1, 2);
|
||||||
let key = self.integers_to_bytevec(temp_v!(1), stub1);
|
let data = self.string_encoding_bytes(3, 4);
|
||||||
let stub2 = MachineError::functor_stub(clause_name!("ed25519_verify"), 4);
|
let stub = MachineError::functor_stub(clause_name!("ed25519_verify"), 5);
|
||||||
let data = self.integers_to_bytevec(temp_v!(2), stub2);
|
let signature = self.integers_to_bytevec(temp_v!(5), stub);
|
||||||
let stub3 = MachineError::functor_stub(clause_name!("ed25519_verify"), 4);
|
|
||||||
let signature = self.integers_to_bytevec(temp_v!(3), stub3);
|
|
||||||
|
|
||||||
let peer_public_key = signature::UnparsedPublicKey::new(&signature::ED25519, &key);
|
let peer_public_key = signature::UnparsedPublicKey::new(&signature::ED25519, &key);
|
||||||
match peer_public_key.verify(&data, &signature) {
|
match peer_public_key.verify(&data, &signature) {
|
||||||
@@ -5665,6 +5655,40 @@ impl MachineState {
|
|||||||
return_from_clause!(self.last_call, self)
|
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)
|
pub(super)
|
||||||
fn xml_node_to_term(
|
fn xml_node_to_term(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|||||||
Reference in New Issue
Block a user