u32 difficulty factor

This commit is contained in:
Aravinth Manivannan 2021-03-08 18:27:18 +05:30
parent e5b4baab3f
commit d1473ae5aa
Signed by: realaravinth
GPG key ID: AD9F0F08E855ED88
8 changed files with 38 additions and 19 deletions

8
CHANGELOG.md Normal file
View file

@ -0,0 +1,8 @@
# Changelog
## 0.1
- PoW constructor
- unique salt
## 0.2
- Difficulty factor is now an unsigned 32 bit number

2
Cargo.lock generated
View file

@ -138,7 +138,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]] [[package]]
name = "pow_sha256" name = "pow_sha256"
version = "0.1.0" version = "0.1.1"
dependencies = [ dependencies = [
"bincode", "bincode",
"derive_builder", "derive_builder",

View file

@ -1,6 +1,6 @@
[package] [package]
name = "pow_sha256" name = "pow_sha256"
version = "0.1.0" version = "0.1.1"
authors = [ "Aravinth Manivannan <realaravinth@bastsense.net>", "Robert Kornacki <robk@syre.io>"] authors = [ "Aravinth Manivannan <realaravinth@bastsense.net>", "Robert Kornacki <robk@syre.io>"]
description = """ description = """
SHA256 PoW on any serializable datatype used in mCaptcha SHA256 PoW on any serializable datatype used in mCaptcha

View file

@ -50,7 +50,7 @@ fn main() {
let phrase = "ironmansucks"; let phrase = "ironmansucks";
const DIFFICULTY: u128 = u128::MAX / 32; const DIFFICULTY: u32 = 1000;
let work = config.prove_work(&phrase, DIFFICULTY).unwrap(); let work = config.prove_work(&phrase, DIFFICULTY).unwrap();
assert!(config.calculate(&work, &phrase).unwrap() >= DIFFICULTY); assert!(config.calculate(&work, &phrase).unwrap() >= DIFFICULTY);
@ -76,7 +76,7 @@ fn main() {
let phrase = "ironmansucks"; let phrase = "ironmansucks";
const DIFFICULTY: u128 = u128::max_value() - u128::max_value() / 100_000; const DIFFICULTY: u32 = 100_000;
let work = config.prove_work(&phrase, DIFFICULTY).unwrap(); let work = config.prove_work(&phrase, DIFFICULTY).unwrap();
@ -131,6 +131,10 @@ fn est_average(difficulty: u128) -> u128 {
} }
``` ```
# License ## Changelog
See [CHANGELOG.md](./CHANGELOG.md)
## License
This project is dual-licensed under `Apache License Version 2.0` or `MIT license`. This project is dual-licensed under `Apache License Version 2.0` or `MIT license`.

View file

@ -12,10 +12,9 @@ fn main() {
let phrase = "ironmansucks"; let phrase = "ironmansucks";
const DIFFICULTY: u128 = u128::MAX / 32; const DIFFICULTY: u32 = 1000;
let work = config.prove_work(&phrase, DIFFICULTY).unwrap(); let work = config.prove_work(&phrase, DIFFICULTY).unwrap();
assert!(config.calculate(&work, &phrase).unwrap() >= DIFFICULTY);
assert!(config.is_valid_proof(&work, &phrase)); assert!(config.is_valid_proof(&work, &phrase));
assert!(config.is_sufficient_difficulty(&work, DIFFICULTY)); assert!(config.is_sufficient_difficulty(&work, DIFFICULTY));
} }

BIN
main Executable file

Binary file not shown.

3
main.rs Normal file
View file

@ -0,0 +1,3 @@
pub fn main() {
println!("{}", u128::MAX / 1000);
}

View file

@ -12,10 +12,9 @@
//! //!
//! let phrase = "ironmansucks"; //! let phrase = "ironmansucks";
//! //!
//! const DIFFICULTY: u128 = u128::MAX / 32; //! const DIFFICULTY: u32 = 1000;
//! //!
//! let work = config.prove_work(&phrase, DIFFICULTY).unwrap(); //! let work = config.prove_work(&phrase, DIFFICULTY).unwrap();
//! assert!(config.calculate(&work, &phrase).unwrap() >= DIFFICULTY);
//! assert!(config.is_valid_proof(&work, &phrase)); //! assert!(config.is_valid_proof(&work, &phrase));
//! assert!(config.is_sufficient_difficulty(&work, DIFFICULTY)); //! assert!(config.is_sufficient_difficulty(&work, DIFFICULTY));
//! } //! }
@ -51,7 +50,7 @@ impl Config {
/// Make sure difficulty is not too high. A 64 bit difficulty, /// Make sure difficulty is not too high. A 64 bit difficulty,
/// for example, takes a long time on a general purpose processor. /// for example, takes a long time on a general purpose processor.
/// Returns bincode::Error if serialization fails. /// Returns bincode::Error if serialization fails.
pub fn prove_work<T>(&self, t: &T, difficulty: u128) -> bincode::Result<PoW<T>> pub fn prove_work<T>(&self, t: &T, difficulty: u32) -> bincode::Result<PoW<T>>
where where
T: Serialize, T: Serialize,
{ {
@ -63,14 +62,14 @@ impl Config {
/// ///
/// Make sure difficulty is not too high. A 64 bit difficulty, /// Make sure difficulty is not too high. A 64 bit difficulty,
/// for example, takes a long time on a general purpose processor. /// for example, takes a long time on a general purpose processor.
pub fn prove_work_serialized<T>(&self, prefix: &[u8], difficulty: u128) -> PoW<T> pub fn prove_work_serialized<T>(&self, prefix: &[u8], difficulty: u32) -> PoW<T>
where where
T: Serialize, T: Serialize,
{ {
let prefix_sha = Sha256::new().chain(&self.salt).chain(prefix); let prefix_sha = Sha256::new().chain(&self.salt).chain(prefix);
let mut n = 0; let mut n = 0;
let mut result = 0; let mut result = 0;
while result < difficulty { while result < get_difficulty(difficulty) {
n += 1; n += 1;
result = score(prefix_sha.clone(), n); result = score(prefix_sha.clone(), n);
} }
@ -116,12 +115,12 @@ impl Config {
} }
/// Checks if the PoW result is of sufficient difficulty /// Checks if the PoW result is of sufficient difficulty
pub fn is_sufficient_difficulty<T>(&self, pow: &PoW<T>, target_diff: u128) -> bool pub fn is_sufficient_difficulty<T>(&self, pow: &PoW<T>, target_diff: u32) -> bool
where where
T: Serialize, T: Serialize,
{ {
match pow.result.parse::<u128>() { match pow.result.parse::<u128>() {
Ok(res) => return res >= target_diff, Ok(res) => return res >= get_difficulty(target_diff),
Err(_) => return false, Err(_) => return false,
} }
} }
@ -143,11 +142,17 @@ fn first_bytes_as_u128(inp: &[u8]) -> u128 {
bincode::deserialize(&inp).unwrap() bincode::deserialize(&inp).unwrap()
} }
// utility function to get u128 difficulty factor from u32
// javacript isn't capable of represnting u128 so
fn get_difficulty(difficulty_factor: u32) -> u128 {
u128::max_value() - u128::max_value() / difficulty_factor as u128
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;
const DIFFICULTY: u128 = 0xff000000000000000000000000000000; const DIFFICULTY: u32 = 1000;
fn get_config() -> Config { fn get_config() -> Config {
ConfigBuilder::default() ConfigBuilder::default()
@ -164,7 +169,7 @@ mod test {
let phrase = b"Ex nihilo nihil fit.".to_vec(); let phrase = b"Ex nihilo nihil fit.".to_vec();
let config = get_config(); let config = get_config();
let pw = config.prove_work(&phrase, DIFFICULTY).unwrap(); let pw = config.prove_work(&phrase, DIFFICULTY).unwrap();
assert!(config.calculate(&pw, &phrase).unwrap() >= DIFFICULTY); assert!(config.calculate(&pw, &phrase).unwrap() >= get_difficulty(DIFFICULTY));
assert!(config.is_valid_proof(&pw, &phrase)); assert!(config.is_valid_proof(&pw, &phrase));
assert!(config.is_sufficient_difficulty(&pw, DIFFICULTY)); assert!(config.is_sufficient_difficulty(&pw, DIFFICULTY));
} }
@ -177,11 +182,11 @@ mod test {
let pw = config.prove_work(&phrase, DIFFICULTY).unwrap(); let pw = config.prove_work(&phrase, DIFFICULTY).unwrap();
let pwpw = config.prove_work(&pw, DIFFICULTY).unwrap(); let pwpw = config.prove_work(&pw, DIFFICULTY).unwrap();
assert!(config.calculate(&pw, &phrase).unwrap() >= DIFFICULTY); assert!(config.calculate(&pw, &phrase).unwrap() >= get_difficulty(DIFFICULTY));
assert!(config.is_valid_proof(&pw, &phrase)); assert!(config.is_valid_proof(&pw, &phrase));
assert!(config.is_sufficient_difficulty(&pw, DIFFICULTY)); assert!(config.is_sufficient_difficulty(&pw, DIFFICULTY));
assert!(config.calculate(&pwpw, &pw).unwrap() >= DIFFICULTY); assert!(config.calculate(&pwpw, &pw).unwrap() >= get_difficulty(DIFFICULTY));
assert!(config.is_valid_proof(&pwpw, &pw)); assert!(config.is_valid_proof(&pwpw, &pw));
assert!(config.is_sufficient_difficulty(&pwpw, DIFFICULTY)); assert!(config.is_sufficient_difficulty(&pwpw, DIFFICULTY));
} }