]> Repositorios git - scryer-prolog.git/commitdiff
ADDED: crypto_n_random_bytes/2, creating cryptographically secure random bytes
authorMarkus Triska <[email protected]>
Tue, 12 May 2020 22:22:17 +0000 (00:22 +0200)
committerMarkus Triska <[email protected]>
Tue, 12 May 2020 22:36:27 +0000 (00:36 +0200)
The ring crate is used since it will be needed also for future
predicates in library(crypto).

Cargo.toml
src/prolog/clause_types.rs
src/prolog/lib/crypto.pl
src/prolog/machine/system_calls.rs

index 4db6b9817d75bd123b5ea75ee0ea2cdf687333a3..8e63ec9a8c2d44be90f1db3de56ad2327beeca83 100644 (file)
@@ -34,3 +34,4 @@ ref_thread_local = "0.0.0"
 rug = { version = "1.4.0", optional = true }
 rustyline = "6.0.0"
 unicode_reader = "1.0.0"
+ring = "0.16.13"
index 36f278df55293561d8c3b6d5caee680274b973a9..0850735c969fe0819abbe77ebd0f4137d9664ec2 100644 (file)
@@ -286,6 +286,7 @@ pub enum SystemClauseType {
     WriteTerm,
     WriteTermToChars,
     ScryerPrologVersion,
+    CryptoRandomByte
 }
 
 impl SystemClauseType {
@@ -468,6 +469,7 @@ impl SystemClauseType {
             &SystemClauseType::WriteTerm => clause_name!("$write_term"),
             &SystemClauseType::WriteTermToChars => clause_name!("$write_term_to_chars"),
             &SystemClauseType::ScryerPrologVersion => clause_name!("$scryer_prolog_version"),
+            &SystemClauseType::CryptoRandomByte => clause_name!("$crypto_random_byte"),
         }
     }
 
@@ -630,6 +632,7 @@ impl SystemClauseType {
             ("$write_term", 7) => Some(SystemClauseType::WriteTerm),
             ("$write_term_to_chars", 7) => Some(SystemClauseType::WriteTermToChars),
             ("$scryer_prolog_version", 1) => Some(SystemClauseType::ScryerPrologVersion),
+            ("$crypto_random_byte", 1) => Some(SystemClauseType::CryptoRandomByte),
             _ => None,
         }
     }
index c91f7de19800e24ea9aaef0b94447ff27426ba75..36f68009598fa71cb5c34f9ed673a48707ad939f 100644 (file)
@@ -12,7 +12,8 @@
    using strings leaves little trace of what was processed in the system,
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 
-:- module(crypto, [hex_bytes/2]).
+:- module(crypto, [hex_bytes/2,
+                   crypto_n_random_bytes/2]).
 
 :- use_module(library(error)).
 :- use_module(library(lists)).
@@ -70,3 +71,10 @@ bytes_hex([B|Bs]) --> [C0,C1],
 char_hexval(C, H) :- nth0(H, "0123456789abcdef", C), !.
 char_hexval(C, H) :- nth0(H, "0123456789ABCDEF", C), !.
 
+
+crypto_n_random_bytes(N, Bs) :-
+        must_be(integer, N),
+        length(Bs, N),
+        maplist(crypto_random_byte, Bs).
+
+crypto_random_byte(B) :- '$crypto_random_byte'(B).
index 86f32fcbb37368f638b44f18d0d7d72adc07298e..343c62b12ab7c209b6c492ef6a84a15ef6b582d2 100644 (file)
@@ -38,6 +38,8 @@ use cpu_time::ProcessTime;
 use crate::crossterm::event::{read, Event, KeyCode, KeyEvent, KeyModifiers};
 use crate::crossterm::terminal::{enable_raw_mode, disable_raw_mode};
 
+use ring::rand::{SecureRandom, SystemRandom};
+
 pub fn get_key() -> KeyEvent {
     let key;
     enable_raw_mode().expect("failed to enable raw mode");
@@ -5137,8 +5139,27 @@ impl MachineState {
                 let result = Addr::HeapCell(self.heap.to_list(chars));
                 self.unify(version, result);
             }
+            &SystemClauseType::CryptoRandomByte => {
+                let arg = self[temp_v!(1)];
+                let mut bytes: Vec<u8> = vec![0];
+                rng().fill(&mut bytes);
+
+                let byte = self.heap.put_constant(Constant::Integer(Rc::new(Integer::from(bytes[0]))));
+                self.unify(arg, byte);
+            }
         };
 
         return_from_clause!(self.last_call, self)
     }
 }
+
+
+fn rng() -> &'static SecureRandom {
+    use std::ops::Deref;
+
+    lazy_static! {
+        static ref RANDOM: SystemRandom = SystemRandom::new();
+    }
+
+    RANDOM.deref()
+}