Merge pull request #533 from triska/master

ADDED: Support for SHA-3 algorithms in crypto_data_hash/3
This commit is contained in:
Mark Thom
2020-05-19 14:23:12 -03:00
committed by GitHub
3 changed files with 70 additions and 33 deletions

View File

@@ -36,3 +36,5 @@ rustyline = "6.0.0"
unicode_reader = "1.0.0" unicode_reader = "1.0.0"
ring = "0.16.13" ring = "0.16.13"
ripemd160 = "0.8.0" ripemd160 = "0.8.0"
sha3 = "0.8.2"
blake2 = "0.8.1"

View File

@@ -158,11 +158,11 @@ crypto_random_byte(B) :- '$crypto_random_byte'(B).
Options is a list of: Options is a list of:
- algorithm(+A) - algorithm(+A)
where A is one of ripemd160, sha256, sha384, sha512, where A is one of ripemd160, sha256, sha384, sha512, sha512_256,
sha512_256, or a variable. If A is a variable, then it is sha3_224, sha3_256, sha3_384, sha3_512, blake2s256, blake2b512,
unified with the default algorithm, which is an algorithm that or a variable. If A is a variable, then it is unified with the
is considered cryptographically secure at the time of this default algorithm, which is an algorithm that is considered
writing. cryptographically secure at the time of this writing.
- encoding(+Encoding) - encoding(+Encoding)
The default encoding is utf8. The alternative is octet, The default encoding is utf8. The alternative is octet,
to treat the input as a list of raw bytes. to treat the input as a list of raw bytes.
@@ -215,6 +215,12 @@ hash_algorithm(sha256).
hash_algorithm(sha512). hash_algorithm(sha512).
hash_algorithm(sha384). hash_algorithm(sha384).
hash_algorithm(sha512_256). hash_algorithm(sha512_256).
hash_algorithm(sha3_224).
hash_algorithm(sha3_256).
hash_algorithm(sha3_384).
hash_algorithm(sha3_512).
hash_algorithm(blake2s256).
hash_algorithm(blake2b512).
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -230,10 +236,9 @@ hash_algorithm(sha512_256).
Admissible options are: Admissible options are:
- algorithm(+Algorithm) - algorithm(+Algorithm)
A hashing algorithm as specified to crypto_data_hash/3. The One of sha256, sha384 or sha512. If you specify a variable,
default is a cryptographically secure algorithm. If you then it is unified with the algorithm that was used, which is a
specify a variable, then it is unified with the algorithm cryptographically secure algorithm by default.
that was used, which is a cryptographically secure algorithm.
- info(+Info) - info(+Info)
Optional context and application specific information, Optional context and application specific information,
specified as a list of bytes or characters. The default is []. specified as a list of bytes or characters. The default is [].
@@ -253,6 +258,9 @@ hash_algorithm(sha512_256).
crypto_data_hkdf(Data0, L, Bytes, Options0) :- crypto_data_hkdf(Data0, L, Bytes, Options0) :-
functor_hash_options(algorithm, Algorithm, Options0, Options), functor_hash_options(algorithm, Algorithm, Options0, Options),
( hkdf_algorithm(Algorithm) -> true
; domain_error(hkdf_algorithm, Algorithm, crypto_data_hkdf/4)
),
must_be(integer, L), must_be(integer, L),
L >= 0, L >= 0,
options_data_bytes(Options, Data0, Data), options_data_bytes(Options, Data0, Data),
@@ -262,6 +270,10 @@ crypto_data_hkdf(Data0, L, Bytes, Options0) :-
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, SaltBytes, Info, Algorithm, L, Bytes).
hkdf_algorithm(sha256).
hkdf_algorithm(sha384).
hkdf_algorithm(sha512).
option(What, Options, Default) :- option(What, Options, Default) :-
( member(V, Options), var(V) -> ( member(V, Options), var(V) ->
instantiation_error(option/3) instantiation_error(option/3)
@@ -587,7 +599,9 @@ crypto_data_decrypt(CipherText0, Algorithm, Key, IV, PlainText, Options) :-
must_be_bytes(Key, crypto_data_decrypt/6), must_be_bytes(Key, crypto_data_decrypt/6),
must_be_bytes(IV, crypto_data_decrypt/6), must_be_bytes(IV, crypto_data_decrypt/6),
must_be(atom, Algorithm), must_be(atom, Algorithm),
encoding_options(Encoding, Options), option(encoding(Encoding), Options, utf8),
must_be(atom, Encoding),
member(Encoding, [utf8,octet]),
must_be(list, CipherText0), must_be(list, CipherText0),
encoding_bytes(octet, CipherText0, CipherText1), encoding_bytes(octet, CipherText0, CipherText1),
append(CipherText1, Tag, CipherText), append(CipherText1, Tag, CipherText),

View File

@@ -42,6 +42,8 @@ use crate::crossterm::terminal::{enable_raw_mode, disable_raw_mode};
use ring::rand::{SecureRandom, SystemRandom}; use ring::rand::{SecureRandom, SystemRandom};
use ring::{digest,hkdf,pbkdf2,aead,error}; use ring::{digest,hkdf,pbkdf2,aead,error};
use ripemd160::{Ripemd160, Digest}; use ripemd160::{Ripemd160, Digest};
use sha3::{Sha3_224, Sha3_256, Sha3_384, Sha3_512};
use blake2::{Blake2s, Blake2b};
pub fn get_key() -> KeyEvent { pub fn get_key() -> KeyEvent {
let key; let key;
@@ -5241,12 +5243,29 @@ impl MachineState {
}; };
let ints_list = let ints_list =
if algorithm_str == "ripemd160" { match algorithm_str {
let mut context = Ripemd160::new(); "sha3_224" => { let mut context = Sha3_224::new();
context.input(&bytes); context.input(&bytes);
Addr::HeapCell(self.heap.to_list(context.result().as_ref().iter().map(|b| HeapCellValue::Integer(Rc::new(Integer::from(*b)))))) Addr::HeapCell(self.heap.to_list(context.result().as_ref().iter().map(|b| HeapCellValue::from(Addr::Fixnum(*b as isize))))) }
} else { "sha3_256" => { let mut context = Sha3_256::new();
let ints = digest::digest( context.input(&bytes);
Addr::HeapCell(self.heap.to_list(context.result().as_ref().iter().map(|b| HeapCellValue::from(Addr::Fixnum(*b as isize))))) }
"sha3_384" => { let mut context = Sha3_384::new();
context.input(&bytes);
Addr::HeapCell(self.heap.to_list(context.result().as_ref().iter().map(|b| HeapCellValue::from(Addr::Fixnum(*b as isize))))) }
"sha3_512" => { let mut context = Sha3_512::new();
context.input(&bytes);
Addr::HeapCell(self.heap.to_list(context.result().as_ref().iter().map(|b| HeapCellValue::from(Addr::Fixnum(*b as isize))))) }
"blake2s256" => { let mut context = Blake2s::new();
context.input(&bytes);
Addr::HeapCell(self.heap.to_list(context.result().as_ref().iter().map(|b| HeapCellValue::from(Addr::Fixnum(*b as isize))))) }
"blake2b512" => { let mut context = Blake2b::new();
context.input(&bytes);
Addr::HeapCell(self.heap.to_list(context.result().as_ref().iter().map(|b| HeapCellValue::from(Addr::Fixnum(*b as isize))))) }
"ripemd160" => { let mut context = Ripemd160::new();
context.input(&bytes);
Addr::HeapCell(self.heap.to_list(context.result().as_ref().iter().map(|b| HeapCellValue::from(Addr::Fixnum(*b as isize))))) }
_ => { let ints = digest::digest(
match algorithm_str { match algorithm_str {
"sha256" => { &digest::SHA256 } "sha256" => { &digest::SHA256 }
"sha384" => { &digest::SHA384 } "sha384" => { &digest::SHA384 }
@@ -5255,7 +5274,8 @@ impl MachineState {
_ => { unreachable!() } _ => { unreachable!() }
}, },
&bytes); &bytes);
Addr::HeapCell(self.heap.to_list(ints.as_ref().iter().map(|b| HeapCellValue::Integer(Rc::new(Integer::from(*b)))))) Addr::HeapCell(self.heap.to_list(ints.as_ref().iter().map(|b| HeapCellValue::from(Addr::Fixnum(*b as isize)))))
}
}; };
self.unify(self[temp_v!(2)], ints_list); self.unify(self[temp_v!(2)], ints_list);
@@ -5287,11 +5307,12 @@ impl MachineState {
usize::try_from(n).unwrap() usize::try_from(n).unwrap()
} }
Ok(Number::Integer(n)) => { Ok(Number::Integer(n)) => {
n.to_usize().unwrap() match n.to_usize() {
Some(u) => { u }
_ => { self.fail = true; return Ok(()); }
} }
_ => {
unreachable!()
} }
_ => { unreachable!() }
}; };
let ints_list = let ints_list =
@@ -5300,7 +5321,7 @@ impl MachineState {
"sha256" => { hkdf::HKDF_SHA256 } "sha256" => { hkdf::HKDF_SHA256 }
"sha384" => { hkdf::HKDF_SHA384 } "sha384" => { hkdf::HKDF_SHA384 }
"sha512" => { hkdf::HKDF_SHA512 } "sha512" => { hkdf::HKDF_SHA512 }
_ => { unreachable!() } _ => { self.fail = true; return Ok(()); }
}; };
let salt = hkdf::Salt::new(digest_alg, &salt); let salt = hkdf::Salt::new(digest_alg, &salt);
let mut bytes : Vec<u8> = Vec::new(); let mut bytes : Vec<u8> = Vec::new();
@@ -5310,7 +5331,7 @@ impl MachineState {
_ => { self.fail = true; return Ok(()); } _ => { self.fail = true; return Ok(()); }
} }
Addr::HeapCell(self.heap.to_list(bytes.iter().map(|b| HeapCellValue::Integer(Rc::new(Integer::from(*b)))))) 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!(6)], ints_list);
@@ -5343,7 +5364,7 @@ impl MachineState {
NonZeroU32::new(iterations as u32).unwrap(), &salt, NonZeroU32::new(iterations as u32).unwrap(), &salt,
&data, &mut bytes); &data, &mut bytes);
Addr::HeapCell(self.heap.to_list(bytes.iter().map(|b| HeapCellValue::Integer(Rc::new(Integer::from(*b)))))) Addr::HeapCell(self.heap.to_list(bytes.iter().map(|b| HeapCellValue::from(Addr::Fixnum(*b as isize)))))
}; };
self.unify(self[temp_v!(4)], ints_list); self.unify(self[temp_v!(4)], ints_list);
@@ -5368,7 +5389,7 @@ impl MachineState {
}; };
let tag_list = let tag_list =
Addr::HeapCell(self.heap.to_list(tag.as_ref().iter().map(|b| HeapCellValue::Integer(Rc::new(Integer::from(*b)))))); Addr::HeapCell(self.heap.to_list(tag.as_ref().iter().map(|b| HeapCellValue::from(Addr::Fixnum(*b as isize)))));
let complete_string = { let complete_string = {
let buffer = String::from_iter(in_out.iter().map(|b| *b as char)); let buffer = String::from_iter(in_out.iter().map(|b| *b as char));