further benchmarking stuff
This commit is contained in:
@@ -2,16 +2,16 @@ const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
var argon2_params = std.crypto.pwhash.argon2.Params{
|
||||
.t = 4, // time cost
|
||||
.m = 256, // memory cost (in KiB)
|
||||
.p = 1, // parallelism (this doesnt do anything because we are targeting wasm, and we do multithreading differently anyways)
|
||||
.t = 3, // time cost
|
||||
.m = 8192, // memory cost (in KiB)
|
||||
.p = 1, // parallelism
|
||||
};
|
||||
|
||||
const dk_len: usize = 32; // 16 or 32 byte key
|
||||
|
||||
pub fn hash(allocator: Allocator, challenge: []const u8, nonce: []const u8) ![]u8 {
|
||||
const derived = try allocator.alloc(u8, dk_len);
|
||||
try std.crypto.pwhash.argon2.kdf(allocator, derived, nonce, challenge, argon2_params, .argon2id);
|
||||
try std.crypto.pwhash.argon2.kdf(allocator, derived, nonce, challenge, argon2_params, .argon2d);
|
||||
|
||||
return derived;
|
||||
}
|
||||
|
||||
@@ -77,18 +77,12 @@ pub const Challenge = struct {
|
||||
const salt_str = challenge;
|
||||
const salt_bytes_len = try std.base64.standard.Decoder.calcSizeForSlice(salt_str);
|
||||
|
||||
std.log.info("salt_bytes_len: {d}\n", .{salt_bytes_len});
|
||||
|
||||
const salt_bytes = try allocator.alloc(u8, salt_bytes_len);
|
||||
defer allocator.free(salt_bytes);
|
||||
|
||||
try std.base64.standard.Decoder.decode(salt_bytes, salt_str);
|
||||
|
||||
std.log.info("decoded salt: {any}\n", .{salt_bytes});
|
||||
|
||||
const usize_salt_bytes: []align(1) usize = std.mem.bytesAsSlice(usize, salt_bytes);
|
||||
// TODO: the bytes are being read in as little endian, but need to be read in as big endian
|
||||
std.log.info("usize_salt_bytes: {any}\n", .{usize_salt_bytes});
|
||||
try salt.ensureCapacity(usize_salt_bytes.len);
|
||||
@memcpy(salt.limbs[0..usize_salt_bytes.len], usize_salt_bytes);
|
||||
salt.setLen(usize_salt_bytes.len);
|
||||
@@ -118,22 +112,16 @@ pub const Challenge = struct {
|
||||
|
||||
pub fn solve(self: *Self, allocator: Allocator) ![]u8 {
|
||||
for (0..self.difficulty) |_| {
|
||||
std.log.info("Solving challenge with difficulty {d}\n", .{self.difficulty});
|
||||
for (0..1277) |_| {
|
||||
try square_mod(&self.salt);
|
||||
}
|
||||
try self.salt.bitXor(&self.salt, &managed_one.?);
|
||||
}
|
||||
|
||||
std.log.info("solved challenge: {any}\n", .{self});
|
||||
|
||||
return try self.encode(allocator);
|
||||
}
|
||||
|
||||
pub fn verify(self: *Self, allocator: Allocator, solution: *Challenge) !bool {
|
||||
std.log.info("{d}", .{self.difficulty});
|
||||
std.log.info("{any} vs {any}\n", .{ self, solution });
|
||||
|
||||
if (managed_one == null) {
|
||||
managed_one = try Int.init(allocator);
|
||||
try managed_one.?.set(1);
|
||||
@@ -145,8 +133,6 @@ pub const Challenge = struct {
|
||||
try square_mod(&solution.salt);
|
||||
}
|
||||
|
||||
std.log.info("{any} vs {any}\n", .{ self, solution });
|
||||
|
||||
// I'm like 99.999% sure this can NEVER happen, but its how the solution that I translated from did it so that's
|
||||
// how I will do it
|
||||
if (self.salt.eql(solution.salt)) {
|
||||
|
||||
@@ -54,9 +54,6 @@ export fn free(ptr: ?*anyopaque, byte_count: usize) void {
|
||||
///
|
||||
/// If a target is not needed for the strategy, target_ptr and target_len should be 0.
|
||||
export fn solve(algorithm: algorithms.Algorithm, strategy: algorithms.Strategy, salt_ptr: [*]u8, salt_len: usize, difficulty: usize, target_ptr: [*]u8, target_len: usize) isize {
|
||||
std.log.info("Solve called with difficulty {d}\n", .{difficulty});
|
||||
std.log.info("Using algorithm {s} and strategy {s}\n", .{ @tagName(algorithm), @tagName(strategy) });
|
||||
|
||||
switch (algorithm) {
|
||||
algorithms.Algorithm.sha256 => return solve_argon2_or_sha256(salt_ptr, salt_len, difficulty, algorithm, strategy, target_ptr, target_len),
|
||||
algorithms.Algorithm.argon2 => return solve_argon2_or_sha256(salt_ptr, salt_len, difficulty, algorithm, strategy, target_ptr, target_len),
|
||||
@@ -95,10 +92,8 @@ fn solve_argon2_or_sha256(salt_ptr: [*]u8, salt_len: usize, difficulty: usize, a
|
||||
return -1;
|
||||
}
|
||||
|
||||
// const max_nonce_iterations: u64 = 1_000_000_000;
|
||||
const max_nonce_iterations: u64 = 100_000;
|
||||
|
||||
std.log.info("Solve called with salt {s}\n", .{salt_slice});
|
||||
const max_nonce_iterations: u64 = 1_000_000_000;
|
||||
// const max_nonce_iterations: u64 = 100_000;
|
||||
|
||||
// 64 + 9 digits for nonce since the max nonce is 999_999_999 (not 1 billion since nonce < max_nonce_iterations)
|
||||
var input_buffer: []u8 = allocator.alloc(u8, salt_len + 9) catch {
|
||||
@@ -131,22 +126,16 @@ fn solve_argon2_or_sha256(salt_ptr: [*]u8, salt_len: usize, difficulty: usize, a
|
||||
return -1;
|
||||
};
|
||||
} else {
|
||||
input = input_buffer[0 .. salt_len + nonce_str.len];
|
||||
}
|
||||
|
||||
const hash_hex_slice = algorithms.SHA256.hash(allocator, input) catch {
|
||||
std.log.err("Error hashing key", .{});
|
||||
return -1;
|
||||
};
|
||||
|
||||
if (algorithm == .argon2) {
|
||||
allocator.free(input);
|
||||
input = algorithms.SHA256.hash(allocator, input_buffer[0 .. salt_len + nonce_str.len]) catch {
|
||||
std.log.err("Error hashing salt", .{});
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
|
||||
switch (strategy) {
|
||||
.leading_zeros => {
|
||||
_ = hex_encoder.encode(hash_hex_slice);
|
||||
allocator.free(hash_hex_slice);
|
||||
_ = hex_encoder.encode(input);
|
||||
allocator.free(input);
|
||||
if (hex_encoder.countZeroes(difficulty)) {
|
||||
// Found a solution!
|
||||
if (__cmpxchg_solution(-1, nonce) == -1) {
|
||||
@@ -159,8 +148,8 @@ fn solve_argon2_or_sha256(salt_ptr: [*]u8, salt_len: usize, difficulty: usize, a
|
||||
}
|
||||
},
|
||||
.target_number => {
|
||||
const hex = hex_encoder.encode(hash_hex_slice);
|
||||
allocator.free(hash_hex_slice);
|
||||
const hex = hex_encoder.encode(input);
|
||||
allocator.free(input);
|
||||
if (std.mem.eql(u8, hex, target_slice.?)) {
|
||||
// Found a solution!
|
||||
if (__cmpxchg_solution(-1, nonce) == -1) {
|
||||
@@ -191,22 +180,17 @@ fn solve_kctf(value_ptr: [*]u8, value_len: usize, difficulty: usize) isize {
|
||||
|
||||
const challenge_slice = value_ptr[0..value_len];
|
||||
|
||||
std.log.info("Solve called with challenge {s}\n", .{challenge_slice});
|
||||
|
||||
const challenge = algorithms.kCTF.Challenge.from_string(allocator, challenge_slice, difficulty) catch |err| {
|
||||
std.log.info("Error decoding challenge: {s}\n", .{@errorName(err)});
|
||||
return -1;
|
||||
};
|
||||
defer challenge.destroy(allocator);
|
||||
|
||||
std.log.info("decoded challenge {any}\n", .{challenge});
|
||||
const solution = challenge.solve(allocator) catch |err| {
|
||||
std.log.info("Error solving challenge: {s}\n", .{@errorName(err)});
|
||||
return -1;
|
||||
};
|
||||
|
||||
std.log.info("Solution: {s}\n", .{solution});
|
||||
|
||||
const output_ptr = allocator.alloc(u8, solution.len + 4) catch return 0;
|
||||
|
||||
var output_slice = output_ptr[0 .. solution.len + 2];
|
||||
|
||||
@@ -74,24 +74,22 @@ fn validate_argon2_or_sha256(challenge_ptr: [*]u8, challenge_len: usize, nonce:
|
||||
var input: []u8 = undefined;
|
||||
if (algorithm == .argon2) {
|
||||
input = algorithms.Argon2.hash(allocator, input_slice[0..challenge_len], input_slice[challenge_len .. challenge_len + nonce_slice.len]) catch return false;
|
||||
defer allocator.free(input);
|
||||
} else {
|
||||
input = input_slice[0 .. challenge_len + nonce_slice.len];
|
||||
input = algorithms.SHA256.hash(allocator, input_slice[0 .. challenge_len + nonce_slice.len]) catch return false;
|
||||
}
|
||||
defer allocator.free(input);
|
||||
|
||||
var hex_encoder = utils.HexEncoder{};
|
||||
const hash_hex_slice = algorithms.SHA256.hash(allocator, input) catch return false;
|
||||
defer allocator.free(hash_hex_slice);
|
||||
|
||||
switch (strategy) {
|
||||
.leading_zeros => {
|
||||
_ = hex_encoder.encode(hash_hex_slice);
|
||||
_ = hex_encoder.encode(input);
|
||||
if (hex_encoder.countZeroes(difficulty)) {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
.target_number => {
|
||||
if (std.mem.eql(u8, hex_encoder.encode(hash_hex_slice), target_slice.?)) {
|
||||
if (std.mem.eql(u8, hex_encoder.encode(input), target_slice.?)) {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
@@ -105,18 +103,13 @@ fn validate_kctf(challenge_ptr: [*]u8, challenge_len: usize, solution_ptr: [*]u8
|
||||
const challenge_buf = challenge_ptr[0..challenge_len];
|
||||
const solution_buf = solution_ptr[0..solution_len];
|
||||
|
||||
std.log.info("Validate called with challenge {s} and solution {s}\n", .{ challenge_buf, solution_buf });
|
||||
|
||||
const challenge = algorithms.kCTF.Challenge.from_string(allocator, challenge_buf, difficulty) catch return false;
|
||||
std.log.info("decoded challenge {any}\n", .{challenge});
|
||||
const solution = algorithms.kCTF.Challenge.from_string(allocator, solution_buf, difficulty) catch return false;
|
||||
defer {
|
||||
challenge.destroy(allocator);
|
||||
solution.destroy(allocator);
|
||||
}
|
||||
|
||||
std.log.info("decoded challenge and solution\n", .{});
|
||||
|
||||
const is_valid = challenge.verify(allocator, solution) catch return false;
|
||||
|
||||
return is_valid;
|
||||
@@ -137,10 +130,7 @@ export fn hash(challenge_ptr: [*]u8, challenge_len: usize, nonce_ptr: [*]u8, non
|
||||
hash_slice = algorithms.SHA256.hash(allocator, input_slice[0 .. challenge_len + nonce_len]) catch return 0;
|
||||
},
|
||||
algorithms.Algorithm.argon2 => {
|
||||
const argon_key = algorithms.Argon2.hash(allocator, challenge, nonce) catch return 0;
|
||||
defer allocator.free(argon_key);
|
||||
|
||||
hash_slice = algorithms.SHA256.hash(allocator, argon_key) catch return 0;
|
||||
hash_slice = algorithms.Argon2.hash(allocator, challenge, nonce) catch return 0;
|
||||
},
|
||||
else => return 0,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user