From 543d213ed9d37f185194864693b849a4a6ea221a Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Mon, 20 Jul 2026 07:20:42 +0100 Subject: [PATCH 01/39] Add randomBytes function for secure random generation Added a function to generate cryptographically secure random bytes. --- src/lib/crypto.buzz | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lib/crypto.buzz b/src/lib/crypto.buzz index d1210ec8..eaeae4ce 100644 --- a/src/lib/crypto.buzz +++ b/src/lib/crypto.buzz @@ -22,3 +22,8 @@ export enum HashAlgorithm { /// @param data Data to hash /// @return Hash of data has hex string export extern fun hash(algo: HashAlgorithm, data: str) > str; + +/// Generate Cryptographically secure randombytes +/// @param len Number of random bytes to generate +/// @return randombytes as string +export extern fn randomBytes(len: int) > str !> errors\CryptoError; From 894bc0ad1c68e536ca05cecc1757431416f6aa62 Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Mon, 20 Jul 2026 07:29:05 +0100 Subject: [PATCH 02/39] Implement randomBytes function in buzz_crypto.zig Add randomBytes function to generate random bytes and push to VM. --- src/lib/buzz_crypto.zig | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/lib/buzz_crypto.zig b/src/lib/buzz_crypto.zig index 16cef50e..b0b5a7cb 100644 --- a/src/lib/buzz_crypto.zig +++ b/src/lib/buzz_crypto.zig @@ -97,9 +97,23 @@ pub export fn hash(ctx: *api.NativeCtx) callconv(.c) c_int { return 1; } +pub export fn randomByes(ctx: *api.NativeCtx) callconv(.c) c_int { + var len: usize = 0; + const len_val = ctx.vm.bz_peek(0); + len = len_val.integer; + var buffer: []u8 = try api.VM.allocator.alloc(u8, len); + defer api.VM.allocator.free(buffer); + std.crypto.random.bytes(buffer); + ctx.vm.bz_push( + api.VM.bz_stringToValue(ctx.vm, buffer.ptr, buffer.len), + ); + return 1; +} + pub const library = api.BuzzApi( "crypto", &.{ &.{ "hash", hash }, + &.{ "randomBytes", randomBytes }, }, ){}; From ddcc330ca6d553b6470590a4087f979beb5aac1a Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Mon, 20 Jul 2026 07:45:02 +0100 Subject: [PATCH 03/39] Replace random bytes generation with Io random --- src/lib/buzz_crypto.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/buzz_crypto.zig b/src/lib/buzz_crypto.zig index b0b5a7cb..56a7a0c6 100644 --- a/src/lib/buzz_crypto.zig +++ b/src/lib/buzz_crypto.zig @@ -103,7 +103,7 @@ pub export fn randomByes(ctx: *api.NativeCtx) callconv(.c) c_int { len = len_val.integer; var buffer: []u8 = try api.VM.allocator.alloc(u8, len); defer api.VM.allocator.free(buffer); - std.crypto.random.bytes(buffer); + std.Io.random(ctx.getIo(), buffer); ctx.vm.bz_push( api.VM.bz_stringToValue(ctx.vm, buffer.ptr, buffer.len), ); From f4115ef82aabd9a63d6cc5b3211bf38888809821 Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Mon, 20 Jul 2026 07:49:15 +0100 Subject: [PATCH 04/39] Update randomBytes function signature Removed error handling from randomBytes function signature. --- src/lib/crypto.buzz | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/crypto.buzz b/src/lib/crypto.buzz index eaeae4ce..335aac34 100644 --- a/src/lib/crypto.buzz +++ b/src/lib/crypto.buzz @@ -26,4 +26,4 @@ export extern fun hash(algo: HashAlgorithm, data: str) > str; /// Generate Cryptographically secure randombytes /// @param len Number of random bytes to generate /// @return randombytes as string -export extern fn randomBytes(len: int) > str !> errors\CryptoError; +export extern fn randomBytes(len: int) > str; From e0702fc80ecb1b0e5167b72db93c2b49b939f17d Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Mon, 20 Jul 2026 07:53:38 +0100 Subject: [PATCH 05/39] Fix typo in randomByes function name to randomBytes --- src/lib/buzz_crypto.zig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/buzz_crypto.zig b/src/lib/buzz_crypto.zig index 56a7a0c6..1bf03ee0 100644 --- a/src/lib/buzz_crypto.zig +++ b/src/lib/buzz_crypto.zig @@ -97,11 +97,11 @@ pub export fn hash(ctx: *api.NativeCtx) callconv(.c) c_int { return 1; } -pub export fn randomByes(ctx: *api.NativeCtx) callconv(.c) c_int { +pub export fn randomBytes(ctx: *api.NativeCtx) callconv(.c) c_int { var len: usize = 0; const len_val = ctx.vm.bz_peek(0); - len = len_val.integer; - var buffer: []u8 = try api.VM.allocator.alloc(u8, len); + len = len_val.integer(); + const buffer: []u8 = try api.VM.allocator.alloc(u8, len); defer api.VM.allocator.free(buffer); std.Io.random(ctx.getIo(), buffer); ctx.vm.bz_push( From fd1ea185e0fed1ea3ec90e7382d4dc06cd34d496 Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Mon, 20 Jul 2026 07:58:00 +0100 Subject: [PATCH 06/39] Fix type casting for length in randomBytes function --- src/lib/buzz_crypto.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/buzz_crypto.zig b/src/lib/buzz_crypto.zig index 1bf03ee0..99040390 100644 --- a/src/lib/buzz_crypto.zig +++ b/src/lib/buzz_crypto.zig @@ -100,7 +100,7 @@ pub export fn hash(ctx: *api.NativeCtx) callconv(.c) c_int { pub export fn randomBytes(ctx: *api.NativeCtx) callconv(.c) c_int { var len: usize = 0; const len_val = ctx.vm.bz_peek(0); - len = len_val.integer(); + len = @as(usize, @intCast(len_val.integer())); const buffer: []u8 = try api.VM.allocator.alloc(u8, len); defer api.VM.allocator.free(buffer); std.Io.random(ctx.getIo(), buffer); From 5ff6610d7f635ca47898488476f3bc944eb4d706 Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Mon, 20 Jul 2026 08:00:28 +0100 Subject: [PATCH 07/39] Fix allocation error in randomBytes function --- src/lib/buzz_crypto.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/buzz_crypto.zig b/src/lib/buzz_crypto.zig index 99040390..32ef396c 100644 --- a/src/lib/buzz_crypto.zig +++ b/src/lib/buzz_crypto.zig @@ -101,7 +101,7 @@ pub export fn randomBytes(ctx: *api.NativeCtx) callconv(.c) c_int { var len: usize = 0; const len_val = ctx.vm.bz_peek(0); len = @as(usize, @intCast(len_val.integer())); - const buffer: []u8 = try api.VM.allocator.alloc(u8, len); + const buffer: []u8 = api.VM.allocator.alloc(u8, len); defer api.VM.allocator.free(buffer); std.Io.random(ctx.getIo(), buffer); ctx.vm.bz_push( From c74c7264a898d8639542e5d820dc19eaf1731c7a Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Mon, 20 Jul 2026 08:11:57 +0100 Subject: [PATCH 08/39] Add error handling for buffer allocation Handle memory allocation failure in randomBytes function. --- src/lib/buzz_crypto.zig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/lib/buzz_crypto.zig b/src/lib/buzz_crypto.zig index 32ef396c..4eab7256 100644 --- a/src/lib/buzz_crypto.zig +++ b/src/lib/buzz_crypto.zig @@ -101,7 +101,10 @@ pub export fn randomBytes(ctx: *api.NativeCtx) callconv(.c) c_int { var len: usize = 0; const len_val = ctx.vm.bz_peek(0); len = @as(usize, @intCast(len_val.integer())); - const buffer: []u8 = api.VM.allocator.alloc(u8, len); + const buffer: []u8 = api.VM.allocator.alloc(u8, len) catch { + ctx.vm.pushError("errors.OutOfMemoryError", null); + return -1; + }; defer api.VM.allocator.free(buffer); std.Io.random(ctx.getIo(), buffer); ctx.vm.bz_push( From 48de21309420d657f7fb4c39db2395962c28ea08 Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Mon, 20 Jul 2026 08:22:20 +0100 Subject: [PATCH 09/39] Change 'fn' to 'fun' in randomBytes declaration --- src/lib/crypto.buzz | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/crypto.buzz b/src/lib/crypto.buzz index 335aac34..0442d40f 100644 --- a/src/lib/crypto.buzz +++ b/src/lib/crypto.buzz @@ -26,4 +26,4 @@ export extern fun hash(algo: HashAlgorithm, data: str) > str; /// Generate Cryptographically secure randombytes /// @param len Number of random bytes to generate /// @return randombytes as string -export extern fn randomBytes(len: int) > str; +export extern fun randomBytes(len: int) > str; From e95b76ff348c4190a693376c025ce2e7ba674d85 Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Mon, 20 Jul 2026 10:45:48 +0100 Subject: [PATCH 10/39] Add cryptographic functions for HMAC and Argon2id --- src/lib/crypto.buzz | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/lib/crypto.buzz b/src/lib/crypto.buzz index 0442d40f..97a00e58 100644 --- a/src/lib/crypto.buzz +++ b/src/lib/crypto.buzz @@ -27,3 +27,31 @@ export extern fun hash(algo: HashAlgorithm, data: str) > str; /// @param len Number of random bytes to generate /// @return randombytes as string export extern fun randomBytes(len: int) > str; + +/// Compute Hmac using Sha-256 +/// @param key the secret key +/// @param data the message to be authenticate +/// @return the Hmac-Sha256 digest (32 byte) +export extern fun hmacSha256(key: str, data: str) > str; + +/// Hash a password using Argon2id +/// @param password The password to hash +/// @param salt The salt (use randomBytes(16) for new hashes) +/// @param memoryCost Memory in KiB (default: 65536) +/// @param timeCost Number of iterations (default: 3) +/// @param parallelism Degree of parallelism (default: 1) +/// @return The encoded hash string +export extern fun argon2id( + password: str, + salt: str, + memoryCost: int?, + timeCost: int?, + parallelism: int? +) > str; + +/// Verify a password against an Argon2id hash +/// @param password The password to verify +/// @param hash The encoded hash string from argon2id() +/// @return true if the password matches the hash +export extern fun verifyArgon2id(password: str, hash: str) > bool; + From f336e6aeaf82accc2b99ab83a5538dc75d152d1d Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Mon, 20 Jul 2026 12:53:09 +0100 Subject: [PATCH 11/39] Add HMAC-SHA256 and Argon2id functions --- src/lib/buzz_crypto.zig | 76 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/src/lib/buzz_crypto.zig b/src/lib/buzz_crypto.zig index 4eab7256..1cd454d7 100644 --- a/src/lib/buzz_crypto.zig +++ b/src/lib/buzz_crypto.zig @@ -113,10 +113,86 @@ pub export fn randomBytes(ctx: *api.NativeCtx) callconv(.c) c_int { return 1; } + +pub export fn hmacSha256(ctx: *api.NativeCtx) callconv(.c) c_int { + var key_len: usize = 0; + const key_ptr = ctx.vm.bz_peek(1).bz_valueToString(&key_len); + const key = key_ptr.?[0..key_len]; + + var data_len: usize = 0; + const data_ptr = ctx.vm.bz_peek(0).bz_valueToString(&data_len); + const data = data_ptr.?[0..data_len]; + + var result: [std.crypto.auth.hmac.HmacSha256.digest_length]u8 = undefined; + std.crypto.auth.hmac.HmacSha256.create(&result, data, key); + + ctx.vm.bz_push( + api.VM.bz_stringToValue(ctx.vm, &result, result.len), + ); + + return 1; +} + +pub export fn argon2id(ctx: *api.NativeCtx) callconv(.c) c_int { + var pass_len: usize = 0; + const pass_ptr = ctx.vm.bz_peek(1).bz_valueToString(&pass_len); + const password = pass_ptr.?[0..pass_len]; + + var salt_len: usize = 0; + const salt_ptr = ctx.vm.bz_peek(0).bz_valueToString(&salt_len); + const salt = salt_ptr.?[0..salt_len]; + + const t_cost: u32 = 3; + const m_cost: u32 = 65536; + const parallelism: u32 = 1; + + var hash_buf: [256]u8 = undefined; + const hash_len = std.crypto.argon2.Argon2id.hash( + &hash_buf, + password, + salt, + t_cost, + m_cost, + parallelism, + ) catch { + ctx.vm.pushError("errors.InvalidArgumentError", "argon2id failed"); + return -1; + }; + + ctx.vm.bz_push( + api.VM.bz_stringToValue(ctx.vm, hash_buf[0..hash_len].ptr, hash_len), + ); + + return 1; +} + +pub export fn verifyArgon2id(ctx: *api.NativeCtx) callconv(.c) c_int { + var pass_len: usize = 0; + const pass_ptr = ctx.vm.bz_peek(1).bz_valueToString(&pass_len); + const password = pass_ptr.?[0..pass_len]; + + var hash_len: usize = 0; + const hash_ptr = ctx.vm.bz_peek(0).bz_valueToString(&hash_len); + const encoded_hash = hash_ptr.?[0..hash_len]; + + const valid = std.crypto.argon2.Argon2id.verify(encoded_hash, password) catch { + ctx.vm.pushError("errors.InvalidArgumentError", "argon2id verification failed"); + return -1; + }; + + ctx.vm.bz_push(api.Value.fromBoolean(valid)); + + return 1; +} + + pub const library = api.BuzzApi( "crypto", &.{ &.{ "hash", hash }, &.{ "randomBytes", randomBytes }, + &.{ "hmacSha256", hmacSha256 }, + &.{ "argon2id", argon2id }, + &.{ "verifyArgon2id", verifyArgon2id }, }, ){}; From 128f47d9fb854807db794b77a4f60845b2e44674 Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Mon, 20 Jul 2026 12:55:05 +0100 Subject: [PATCH 12/39] Simplify argon2id function parameters Removed optional parameters from argon2id function signature. --- src/lib/crypto.buzz | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/lib/crypto.buzz b/src/lib/crypto.buzz index 97a00e58..65660b52 100644 --- a/src/lib/crypto.buzz +++ b/src/lib/crypto.buzz @@ -37,16 +37,10 @@ export extern fun hmacSha256(key: str, data: str) > str; /// Hash a password using Argon2id /// @param password The password to hash /// @param salt The salt (use randomBytes(16) for new hashes) -/// @param memoryCost Memory in KiB (default: 65536) -/// @param timeCost Number of iterations (default: 3) -/// @param parallelism Degree of parallelism (default: 1) /// @return The encoded hash string export extern fun argon2id( password: str, - salt: str, - memoryCost: int?, - timeCost: int?, - parallelism: int? + salt: str ) > str; /// Verify a password against an Argon2id hash @@ -54,4 +48,3 @@ export extern fun argon2id( /// @param hash The encoded hash string from argon2id() /// @return true if the password matches the hash export extern fun verifyArgon2id(password: str, hash: str) > bool; - From 498ce2a016e1bd1de03b6abd92fe509255e137d1 Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Mon, 20 Jul 2026 13:22:11 +0100 Subject: [PATCH 13/39] Refactor cryptographic functions for consistency --- src/lib/buzz_crypto.zig | 55 +++++++++++++---------------------------- 1 file changed, 17 insertions(+), 38 deletions(-) diff --git a/src/lib/buzz_crypto.zig b/src/lib/buzz_crypto.zig index 1cd454d7..bdcc30ed 100644 --- a/src/lib/buzz_crypto.zig +++ b/src/lib/buzz_crypto.zig @@ -114,26 +114,7 @@ pub export fn randomBytes(ctx: *api.NativeCtx) callconv(.c) c_int { } -pub export fn hmacSha256(ctx: *api.NativeCtx) callconv(.c) c_int { - var key_len: usize = 0; - const key_ptr = ctx.vm.bz_peek(1).bz_valueToString(&key_len); - const key = key_ptr.?[0..key_len]; - - var data_len: usize = 0; - const data_ptr = ctx.vm.bz_peek(0).bz_valueToString(&data_len); - const data = data_ptr.?[0..data_len]; - - var result: [std.crypto.auth.hmac.HmacSha256.digest_length]u8 = undefined; - std.crypto.auth.hmac.HmacSha256.create(&result, data, key); - - ctx.vm.bz_push( - api.VM.bz_stringToValue(ctx.vm, &result, result.len), - ); - - return 1; -} - -pub export fn argon2id(ctx: *api.NativeCtx) callconv(.c) c_int { +pub export fn argon2(ctx: *api.NativeCtx) callconv(.c) c_int { var pass_len: usize = 0; const pass_ptr = ctx.vm.bz_peek(1).bz_valueToString(&pass_len); const password = pass_ptr.?[0..pass_len]; @@ -144,21 +125,20 @@ pub export fn argon2id(ctx: *api.NativeCtx) callconv(.c) c_int { const t_cost: u32 = 3; const m_cost: u32 = 65536; - const parallelism: u32 = 1; + const parallelism: u24 = 1; var hash_buf: [256]u8 = undefined; - const hash_len = std.crypto.argon2.Argon2id.hash( - &hash_buf, - password, - salt, - t_cost, - m_cost, - parallelism, - ) catch { - ctx.vm.pushError("errors.InvalidArgumentError", "argon2id failed"); + const hash_len = std.crypto.pwhash.argon2.strHash( + password, + .{ .allocator = api.vm.allocator, + .params = .{ .t = t_cost, .m = m_cost, .p = parallelism }, + }, + &hash_buf, + ctx.getIo(); + ) catch { + ctx.vm.pushError("errors.AuthenticationFailed", "argon2 failed"); return -1; - }; - + }; ctx.vm.bz_push( api.VM.bz_stringToValue(ctx.vm, hash_buf[0..hash_len].ptr, hash_len), ); @@ -166,7 +146,7 @@ pub export fn argon2id(ctx: *api.NativeCtx) callconv(.c) c_int { return 1; } -pub export fn verifyArgon2id(ctx: *api.NativeCtx) callconv(.c) c_int { +pub export fn verifyArgon2(ctx: *api.NativeCtx) callconv(.c) c_int { var pass_len: usize = 0; const pass_ptr = ctx.vm.bz_peek(1).bz_valueToString(&pass_len); const password = pass_ptr.?[0..pass_len]; @@ -175,8 +155,8 @@ pub export fn verifyArgon2id(ctx: *api.NativeCtx) callconv(.c) c_int { const hash_ptr = ctx.vm.bz_peek(0).bz_valueToString(&hash_len); const encoded_hash = hash_ptr.?[0..hash_len]; - const valid = std.crypto.argon2.Argon2id.verify(encoded_hash, password) catch { - ctx.vm.pushError("errors.InvalidArgumentError", "argon2id verification failed"); + const valid = std.crypto.pwhash.argon2.strVerify(encoded_hash, password, .{ .allocator = api.vm.allocator }, ctx.getIo()) catch { + ctx.vm.pushError("errors.AuthenticationFailed", "argon2 verification failed"); return -1; }; @@ -191,8 +171,7 @@ pub const library = api.BuzzApi( &.{ &.{ "hash", hash }, &.{ "randomBytes", randomBytes }, - &.{ "hmacSha256", hmacSha256 }, - &.{ "argon2id", argon2id }, - &.{ "verifyArgon2id", verifyArgon2id }, + &.{ "argon2", argon2 }, + &.{ "verifyArgon2", verifyArgon2 }, }, ){}; From 0f8cd16b084133bafa6ed925903418e760b28a80 Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Mon, 20 Jul 2026 13:24:25 +0100 Subject: [PATCH 14/39] Refactor HMAC and Argon2 functions in crypto.buzz --- src/lib/crypto.buzz | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/lib/crypto.buzz b/src/lib/crypto.buzz index 65660b52..317ea34f 100644 --- a/src/lib/crypto.buzz +++ b/src/lib/crypto.buzz @@ -28,17 +28,12 @@ export extern fun hash(algo: HashAlgorithm, data: str) > str; /// @return randombytes as string export extern fun randomBytes(len: int) > str; -/// Compute Hmac using Sha-256 -/// @param key the secret key -/// @param data the message to be authenticate -/// @return the Hmac-Sha256 digest (32 byte) -export extern fun hmacSha256(key: str, data: str) > str; /// Hash a password using Argon2id /// @param password The password to hash /// @param salt The salt (use randomBytes(16) for new hashes) /// @return The encoded hash string -export extern fun argon2id( +export extern fun argon2( password: str, salt: str ) > str; @@ -47,4 +42,4 @@ export extern fun argon2id( /// @param password The password to verify /// @param hash The encoded hash string from argon2id() /// @return true if the password matches the hash -export extern fun verifyArgon2id(password: str, hash: str) > bool; +export extern fun verifyArgon2(password: str, hash: str) > bool; From 1607555cf34a660bc41d93f8d3ea68bf8a7ecdb5 Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Mon, 20 Jul 2026 13:27:08 +0100 Subject: [PATCH 15/39] Fix argon2 hash call to use io from context --- src/lib/buzz_crypto.zig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib/buzz_crypto.zig b/src/lib/buzz_crypto.zig index bdcc30ed..07b70a64 100644 --- a/src/lib/buzz_crypto.zig +++ b/src/lib/buzz_crypto.zig @@ -128,13 +128,14 @@ pub export fn argon2(ctx: *api.NativeCtx) callconv(.c) c_int { const parallelism: u24 = 1; var hash_buf: [256]u8 = undefined; + const io = ctx.getIo(); const hash_len = std.crypto.pwhash.argon2.strHash( password, .{ .allocator = api.vm.allocator, .params = .{ .t = t_cost, .m = m_cost, .p = parallelism }, }, &hash_buf, - ctx.getIo(); + io ) catch { ctx.vm.pushError("errors.AuthenticationFailed", "argon2 failed"); return -1; From 2d252cea1d55a8a8cbb858ececd89e54c0fd8614 Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Mon, 20 Jul 2026 13:33:50 +0100 Subject: [PATCH 16/39] Fix argon2 function to use correct context allocator --- src/lib/buzz_crypto.zig | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/lib/buzz_crypto.zig b/src/lib/buzz_crypto.zig index 07b70a64..ee56dcf3 100644 --- a/src/lib/buzz_crypto.zig +++ b/src/lib/buzz_crypto.zig @@ -116,13 +116,8 @@ pub export fn randomBytes(ctx: *api.NativeCtx) callconv(.c) c_int { pub export fn argon2(ctx: *api.NativeCtx) callconv(.c) c_int { var pass_len: usize = 0; - const pass_ptr = ctx.vm.bz_peek(1).bz_valueToString(&pass_len); + const pass_ptr = ctx.vm.bz_peek(0).bz_valueToString(&pass_len); const password = pass_ptr.?[0..pass_len]; - - var salt_len: usize = 0; - const salt_ptr = ctx.vm.bz_peek(0).bz_valueToString(&salt_len); - const salt = salt_ptr.?[0..salt_len]; - const t_cost: u32 = 3; const m_cost: u32 = 65536; const parallelism: u24 = 1; @@ -131,7 +126,7 @@ pub export fn argon2(ctx: *api.NativeCtx) callconv(.c) c_int { const io = ctx.getIo(); const hash_len = std.crypto.pwhash.argon2.strHash( password, - .{ .allocator = api.vm.allocator, + .{ .allocator = api.VM.allocator, .params = .{ .t = t_cost, .m = m_cost, .p = parallelism }, }, &hash_buf, @@ -156,7 +151,7 @@ pub export fn verifyArgon2(ctx: *api.NativeCtx) callconv(.c) c_int { const hash_ptr = ctx.vm.bz_peek(0).bz_valueToString(&hash_len); const encoded_hash = hash_ptr.?[0..hash_len]; - const valid = std.crypto.pwhash.argon2.strVerify(encoded_hash, password, .{ .allocator = api.vm.allocator }, ctx.getIo()) catch { + const valid = std.crypto.pwhash.argon2.strVerify(encoded_hash, password, .{ .allocator = api.VM.allocator }, ctx.getIo()) catch { ctx.vm.pushError("errors.AuthenticationFailed", "argon2 verification failed"); return -1; }; From 91dd93533e22b6cb99c6da8f7b5a7159f90ee730 Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Mon, 20 Jul 2026 13:34:50 +0100 Subject: [PATCH 17/39] Update argon2 function documentation Removed the salt parameter from the argon2 function documentation. --- src/lib/crypto.buzz | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/lib/crypto.buzz b/src/lib/crypto.buzz index 317ea34f..79df1e4d 100644 --- a/src/lib/crypto.buzz +++ b/src/lib/crypto.buzz @@ -31,11 +31,9 @@ export extern fun randomBytes(len: int) > str; /// Hash a password using Argon2id /// @param password The password to hash -/// @param salt The salt (use randomBytes(16) for new hashes) /// @return The encoded hash string export extern fun argon2( password: str, - salt: str ) > str; /// Verify a password against an Argon2id hash From f48c9070cc467f4eba7b6e3dfab2618308e69e25 Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Mon, 20 Jul 2026 13:42:45 +0100 Subject: [PATCH 18/39] Fix hash buffer reference and push true for validation --- src/lib/buzz_crypto.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/buzz_crypto.zig b/src/lib/buzz_crypto.zig index ee56dcf3..d36f81e9 100644 --- a/src/lib/buzz_crypto.zig +++ b/src/lib/buzz_crypto.zig @@ -136,7 +136,7 @@ pub export fn argon2(ctx: *api.NativeCtx) callconv(.c) c_int { return -1; }; ctx.vm.bz_push( - api.VM.bz_stringToValue(ctx.vm, hash_buf[0..hash_len].ptr, hash_len), + api.VM.bz_stringToValue(ctx.vm, &hash_buf, hash_len), ); return 1; @@ -156,7 +156,7 @@ pub export fn verifyArgon2(ctx: *api.NativeCtx) callconv(.c) c_int { return -1; }; - ctx.vm.bz_push(api.Value.fromBoolean(valid)); + ctx.vm.bz_push(api.Value.fromBoolean(true)); return 1; } From e64bd89686480139d264a69ccc1cfa7a4412cc24 Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Mon, 20 Jul 2026 13:55:40 +0100 Subject: [PATCH 19/39] Fix hash variable assignment in buzz_crypto.zig --- src/lib/buzz_crypto.zig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/buzz_crypto.zig b/src/lib/buzz_crypto.zig index d36f81e9..3e6bbd89 100644 --- a/src/lib/buzz_crypto.zig +++ b/src/lib/buzz_crypto.zig @@ -124,7 +124,7 @@ pub export fn argon2(ctx: *api.NativeCtx) callconv(.c) c_int { var hash_buf: [256]u8 = undefined; const io = ctx.getIo(); - const hash_len = std.crypto.pwhash.argon2.strHash( + const hash = std.crypto.pwhash.argon2.strHash( password, .{ .allocator = api.VM.allocator, .params = .{ .t = t_cost, .m = m_cost, .p = parallelism }, @@ -136,7 +136,7 @@ pub export fn argon2(ctx: *api.NativeCtx) callconv(.c) c_int { return -1; }; ctx.vm.bz_push( - api.VM.bz_stringToValue(ctx.vm, &hash_buf, hash_len), + api.VM.bz_stringToValue(ctx.vm, hash.ptr, hash.len), ); return 1; @@ -151,7 +151,7 @@ pub export fn verifyArgon2(ctx: *api.NativeCtx) callconv(.c) c_int { const hash_ptr = ctx.vm.bz_peek(0).bz_valueToString(&hash_len); const encoded_hash = hash_ptr.?[0..hash_len]; - const valid = std.crypto.pwhash.argon2.strVerify(encoded_hash, password, .{ .allocator = api.VM.allocator }, ctx.getIo()) catch { + std.crypto.pwhash.argon2.strVerify(encoded_hash, password, .{ .allocator = api.VM.allocator }, ctx.getIo()) catch { ctx.vm.pushError("errors.AuthenticationFailed", "argon2 verification failed"); return -1; }; From 9bc204320a5bcabb236ba346f1340612e39aa136 Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Mon, 20 Jul 2026 14:04:09 +0100 Subject: [PATCH 20/39] Fix variable name for Argon2 hash result --- src/lib/buzz_crypto.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/buzz_crypto.zig b/src/lib/buzz_crypto.zig index 3e6bbd89..1f9246dd 100644 --- a/src/lib/buzz_crypto.zig +++ b/src/lib/buzz_crypto.zig @@ -124,7 +124,7 @@ pub export fn argon2(ctx: *api.NativeCtx) callconv(.c) c_int { var hash_buf: [256]u8 = undefined; const io = ctx.getIo(); - const hash = std.crypto.pwhash.argon2.strHash( + const hash_r = std.crypto.pwhash.argon2.strHash( password, .{ .allocator = api.VM.allocator, .params = .{ .t = t_cost, .m = m_cost, .p = parallelism }, @@ -136,7 +136,7 @@ pub export fn argon2(ctx: *api.NativeCtx) callconv(.c) c_int { return -1; }; ctx.vm.bz_push( - api.VM.bz_stringToValue(ctx.vm, hash.ptr, hash.len), + api.VM.bz_stringToValue(ctx.vm, hash_r.ptr, hash_r.len), ); return 1; From 85d934ac575f8a43cb921e4fc3893532777c3b8c Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Mon, 20 Jul 2026 18:22:13 +0100 Subject: [PATCH 21/39] Change wasm_native flag for crypto library to false --- src/lib/static_libraries.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/static_libraries.zig b/src/lib/static_libraries.zig index 6463a3c5..2d1db335 100644 --- a/src/lib/static_libraries.zig +++ b/src/lib/static_libraries.zig @@ -17,7 +17,7 @@ pub const Library = struct { /// Libraries bundled with the compiler and runtime. pub const all = [_]Library{ .{ .header = static_headers.buffer, .zig_path = "buzz_buffer.zig", .wasm_native = true }, - .{ .header = static_headers.crypto, .zig_path = "buzz_crypto.zig", .wasm_native = true }, + .{ .header = static_headers.crypto, .zig_path = "buzz_crypto.zig", .wasm_native = false }, .{ .header = static_headers.debug, .zig_path = "buzz_debug.zig", .wasm_native = true }, .{ .header = static_headers.errors, .zig_path = null, .wasm_native = false }, .{ .header = static_headers.ffi, .zig_path = "buzz_ffi.zig", .wasm_native = false }, From c77b726d0f0e38a502effda3234015dee5380910 Mon Sep 17 00:00:00 2001 From: zendrx Date: Mon, 20 Jul 2026 22:16:24 +0100 Subject: [PATCH 22/39] Update buzz_crypto.zig --- src/lib/buzz_crypto.zig | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/src/lib/buzz_crypto.zig b/src/lib/buzz_crypto.zig index 1f9246dd..f951508f 100644 --- a/src/lib/buzz_crypto.zig +++ b/src/lib/buzz_crypto.zig @@ -98,22 +98,21 @@ pub export fn hash(ctx: *api.NativeCtx) callconv(.c) c_int { } pub export fn randomBytes(ctx: *api.NativeCtx) callconv(.c) c_int { - var len: usize = 0; - const len_val = ctx.vm.bz_peek(0); - len = @as(usize, @intCast(len_val.integer())); - const buffer: []u8 = api.VM.allocator.alloc(u8, len) catch { - ctx.vm.pushError("errors.OutOfMemoryError", null); - return -1; - }; - defer api.VM.allocator.free(buffer); - std.Io.random(ctx.getIo(), buffer); - ctx.vm.bz_push( - api.VM.bz_stringToValue(ctx.vm, buffer.ptr, buffer.len), + var len: usize = 0; + const len_val = ctx.vm.bz_peek(0); + len = @as(usize, @intCast(len_val.integer())); + const buffer: []u8 = api.VM.allocator.alloc(u8, len) catch { + ctx.vm.pushError("errors.OutOfMemoryError", null); + return -1; + }; + defer api.VM.allocator.free(buffer); + std.Io.random(ctx.getIo(), buffer); + ctx.vm.bz_push( + api.VM.bz_stringToValue(ctx.vm, buffer.ptr, buffer.len), ); - return 1; + return 1; } - pub export fn argon2(ctx: *api.NativeCtx) callconv(.c) c_int { var pass_len: usize = 0; const pass_ptr = ctx.vm.bz_peek(0).bz_valueToString(&pass_len); @@ -124,17 +123,13 @@ pub export fn argon2(ctx: *api.NativeCtx) callconv(.c) c_int { var hash_buf: [256]u8 = undefined; const io = ctx.getIo(); - const hash_r = std.crypto.pwhash.argon2.strHash( - password, - .{ .allocator = api.VM.allocator, - .params = .{ .t = t_cost, .m = m_cost, .p = parallelism }, - }, - &hash_buf, - io - ) catch { + const hash_r = std.crypto.pwhash.argon2.strHash(password, .{ + .allocator = api.VM.allocator, + .params = .{ .t = t_cost, .m = m_cost, .p = parallelism }, + }, &hash_buf, io) catch { ctx.vm.pushError("errors.AuthenticationFailed", "argon2 failed"); return -1; - }; + }; ctx.vm.bz_push( api.VM.bz_stringToValue(ctx.vm, hash_r.ptr, hash_r.len), ); @@ -160,7 +155,6 @@ pub export fn verifyArgon2(ctx: *api.NativeCtx) callconv(.c) c_int { return 1; } - pub const library = api.BuzzApi( "crypto", From fa541868133d22be071eb8eef8bc51ce2bbd4de5 Mon Sep 17 00:00:00 2001 From: zendrx Date: Tue, 21 Jul 2026 13:29:12 +0100 Subject: [PATCH 23/39] fixed type redundant --- src/lib/buzz_crypto.zig | 12 ++++-------- src/lib/crypto.buzz | 6 +++--- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/lib/buzz_crypto.zig b/src/lib/buzz_crypto.zig index f951508f..961cd83e 100644 --- a/src/lib/buzz_crypto.zig +++ b/src/lib/buzz_crypto.zig @@ -98,10 +98,10 @@ pub export fn hash(ctx: *api.NativeCtx) callconv(.c) c_int { } pub export fn randomBytes(ctx: *api.NativeCtx) callconv(.c) c_int { - var len: usize = 0; + const len: usize = 0; const len_val = ctx.vm.bz_peek(0); len = @as(usize, @intCast(len_val.integer())); - const buffer: []u8 = api.VM.allocator.alloc(u8, len) catch { + const buffer = api.VM.allocator.alloc(u8, len) catch { ctx.vm.pushError("errors.OutOfMemoryError", null); return -1; }; @@ -117,15 +117,11 @@ pub export fn argon2(ctx: *api.NativeCtx) callconv(.c) c_int { var pass_len: usize = 0; const pass_ptr = ctx.vm.bz_peek(0).bz_valueToString(&pass_len); const password = pass_ptr.?[0..pass_len]; - const t_cost: u32 = 3; - const m_cost: u32 = 65536; - const parallelism: u24 = 1; - var hash_buf: [256]u8 = undefined; const io = ctx.getIo(); const hash_r = std.crypto.pwhash.argon2.strHash(password, .{ .allocator = api.VM.allocator, - .params = .{ .t = t_cost, .m = m_cost, .p = parallelism }, + .params = .{ .t = 2, .m = 19 * 1024, .p = 1 }, }, &hash_buf, io) catch { ctx.vm.pushError("errors.AuthenticationFailed", "argon2 failed"); return -1; @@ -151,7 +147,7 @@ pub export fn verifyArgon2(ctx: *api.NativeCtx) callconv(.c) c_int { return -1; }; - ctx.vm.bz_push(api.Value.fromBoolean(true)); + ctx.vm.bz_push(.True); return 1; } diff --git a/src/lib/crypto.buzz b/src/lib/crypto.buzz index 79df1e4d..c30e19f5 100644 --- a/src/lib/crypto.buzz +++ b/src/lib/crypto.buzz @@ -1,5 +1,7 @@ namespace crypto; +import "buzz:errors"; + /// Hash algorithms export enum HashAlgorithm { Md5, @@ -32,9 +34,7 @@ export extern fun randomBytes(len: int) > str; /// Hash a password using Argon2id /// @param password The password to hash /// @return The encoded hash string -export extern fun argon2( - password: str, -) > str; +export extern fun argon2(password: str) > str; /// Verify a password against an Argon2id hash /// @param password The password to verify From c95432b6591a9bf3459b4d9b1af1afe6b9bb19f0 Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Tue, 21 Jul 2026 19:39:05 +0100 Subject: [PATCH 24/39] Change len from const to var in randomBytes function --- src/lib/buzz_crypto.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/buzz_crypto.zig b/src/lib/buzz_crypto.zig index 961cd83e..81583655 100644 --- a/src/lib/buzz_crypto.zig +++ b/src/lib/buzz_crypto.zig @@ -98,7 +98,7 @@ pub export fn hash(ctx: *api.NativeCtx) callconv(.c) c_int { } pub export fn randomBytes(ctx: *api.NativeCtx) callconv(.c) c_int { - const len: usize = 0; + var len: usize = 0; const len_val = ctx.vm.bz_peek(0); len = @as(usize, @intCast(len_val.integer())); const buffer = api.VM.allocator.alloc(u8, len) catch { From 5e99af2e6ef9ea8759e773bbd4814d5217b02f8b Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Tue, 21 Jul 2026 19:40:05 +0100 Subject: [PATCH 25/39] Change variable declaration from var to const --- src/lib/buzz_crypto.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/buzz_crypto.zig b/src/lib/buzz_crypto.zig index 81583655..961cd83e 100644 --- a/src/lib/buzz_crypto.zig +++ b/src/lib/buzz_crypto.zig @@ -98,7 +98,7 @@ pub export fn hash(ctx: *api.NativeCtx) callconv(.c) c_int { } pub export fn randomBytes(ctx: *api.NativeCtx) callconv(.c) c_int { - var len: usize = 0; + const len: usize = 0; const len_val = ctx.vm.bz_peek(0); len = @as(usize, @intCast(len_val.integer())); const buffer = api.VM.allocator.alloc(u8, len) catch { From 3d306d3ae45107fe4b70e5d9eb3247831bc9a8d4 Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Tue, 21 Jul 2026 19:45:49 +0100 Subject: [PATCH 26/39] Change len to var for reassignment in randomBytes Change 'len' from a constant to a variable to allow reassignment. --- src/lib/buzz_crypto.zig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib/buzz_crypto.zig b/src/lib/buzz_crypto.zig index 961cd83e..6c813f52 100644 --- a/src/lib/buzz_crypto.zig +++ b/src/lib/buzz_crypto.zig @@ -98,7 +98,8 @@ pub export fn hash(ctx: *api.NativeCtx) callconv(.c) c_int { } pub export fn randomBytes(ctx: *api.NativeCtx) callconv(.c) c_int { - const len: usize = 0; + // needs to be var due to reassignment on line #104 + var len: usize = 0; const len_val = ctx.vm.bz_peek(0); len = @as(usize, @intCast(len_val.integer())); const buffer = api.VM.allocator.alloc(u8, len) catch { From 1c80129cdd1ccb221fcef05f5630c593c979bac8 Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Wed, 22 Jul 2026 16:33:45 +0100 Subject: [PATCH 27/39] Refactor randomBytes function to use const for len --- src/lib/buzz_crypto.zig | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/lib/buzz_crypto.zig b/src/lib/buzz_crypto.zig index 6c813f52..2091100b 100644 --- a/src/lib/buzz_crypto.zig +++ b/src/lib/buzz_crypto.zig @@ -98,10 +98,8 @@ pub export fn hash(ctx: *api.NativeCtx) callconv(.c) c_int { } pub export fn randomBytes(ctx: *api.NativeCtx) callconv(.c) c_int { - // needs to be var due to reassignment on line #104 - var len: usize = 0; const len_val = ctx.vm.bz_peek(0); - len = @as(usize, @intCast(len_val.integer())); + const len = @as(usize, @intCast(len_val.integer())); const buffer = api.VM.allocator.alloc(u8, len) catch { ctx.vm.pushError("errors.OutOfMemoryError", null); return -1; From 38945d8adaa3c77709007decb18a43b01e8c30ed Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Thu, 23 Jul 2026 18:18:21 +0100 Subject: [PATCH 28/39] Add randomBytes tests --- tests/behavior/crypto.buzz | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/behavior/crypto.buzz b/tests/behavior/crypto.buzz index 2b00bb11..08c75a4d 100644 --- a/tests/behavior/crypto.buzz +++ b/tests/behavior/crypto.buzz @@ -28,3 +28,16 @@ test "hash" { message: "sha3-256", ); } + +test "randomBytes returns correct length" { + final len = 16; + final bytes = crypto\randomBytes(len); + std\assert(bytes.len == len, "randomBytes should return a string of the requested length"); +} + +test "randomBytes returns different values" { + final b1 = crypto\randomBytes(8); + final b2 = crypto\randomBytes(8); + std\assert(b1 != b2, "randomBytes should return different values"); +} + From afb2497c1692f2bc1c6a4b6b5d4e428093a9f439 Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Thu, 23 Jul 2026 18:35:01 +0100 Subject: [PATCH 29/39] Refactor crypto test cases to use updated imports --- tests/behavior/crypto.buzz | 75 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 4 deletions(-) diff --git a/tests/behavior/crypto.buzz b/tests/behavior/crypto.buzz index 08c75a4d..33ba0f3c 100644 --- a/tests/behavior/crypto.buzz +++ b/tests/behavior/crypto.buzz @@ -29,15 +29,82 @@ test "hash" { ); } +import "buzz:std"; +import "buzz:crypto" as _; + +test "hash" { + std\assert( + "c3fcd3d76192e4007dfb496cca67e13b" == hash( + .Md5, + data: "abcdefghijklmnopqrstuvwxyz" + ).hex(), + message: "md5", + ); + + std\assert( + "a9993e364706816aba3e25717850c26c9cd0d89d" + == hash(.Sha1, data: "abc").hex(), + message: "sha1", + ); + + std\assert( + "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" + == hash(.Sha256, data: "abc").hex(), + message: "sha256", + ); + + std\assert( + "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532" + == hash(.Sha3256, data: "abc").hex(), + message: "sha3-256", + ); +} + test "randomBytes returns correct length" { final len = 16; - final bytes = crypto\randomBytes(len); - std\assert(bytes.len == len, "randomBytes should return a string of the requested length"); + final bytes = randomBytes(len); + std\assert(bytes.len() == len, "randomBytes should return a string of the requested length"); } test "randomBytes returns different values" { - final b1 = crypto\randomBytes(8); - final b2 = crypto\randomBytes(8); + final b1 = randomBytes(8); + final b2 = randomBytes(8); std\assert(b1 != b2, "randomBytes should return different values"); } +test "argon2 hashes and verifies" { + final password = "my-secure-password"; + final hash = argon2(password) ! { + std\assert(false, "argon2 failed: {}", .{error}); + return; + }; + final valid = verifyArgon2(password, hash) ! { + std\assert(false, "verifyArgon2 failed: {}", .{error}); + return; + }; + std\assert(valid, "argon2 verification should succeed for correct password"); +} + +test "argon2 fails for wrong password" { + final password = "my-secure-password"; + final wrong = "wrong-password"; + final hash = argon2(password) ! { + std\assert(false, "argon2 failed: {}", .{error}); + return; + }; + final valid = verifyArgon2(wrong, hash) ! { + std\assert(false, "verifyArgon2 failed: {}", .{error}); + return; + }; + std\assert(!valid, "argon2 verification should fail for wrong password"); +} + +test "argon2 handles invalid hash" { + final result = verifyArgon2("password", "invalid-hash"); + if (result -> _) { + std\assert(false, "verifyArgon2 should fail for invalid hash"); + } else { + // Expected error – test passes + } +} + From 888f5beaf3856c0b613e330a2e6e09809422b4dc Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Thu, 23 Jul 2026 18:35:39 +0100 Subject: [PATCH 30/39] Refactor hash test cases in crypto.buzz Removed redundant hash tests for different algorithms. --- tests/behavior/crypto.buzz | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/tests/behavior/crypto.buzz b/tests/behavior/crypto.buzz index 33ba0f3c..40f8e301 100644 --- a/tests/behavior/crypto.buzz +++ b/tests/behavior/crypto.buzz @@ -1,33 +1,3 @@ -import "buzz:std"; -import "buzz:crypto" as _; - -test "hash" { - std\assert( - "c3fcd3d76192e4007dfb496cca67e13b" == hash( - .Md5, - data: "abcdefghijklmnopqrstuvwxyz" - ).hex(), - message: "md5", - ); - - std\assert( - "a9993e364706816aba3e25717850c26c9cd0d89d" - == hash(.Sha1, data: "abc").hex(), - message: "sha1", - ); - - std\assert( - "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" - == hash(.Sha256, data: "abc").hex(), - message: "sha256", - ); - - std\assert( - "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532" - == hash(.Sha3256, data: "abc").hex(), - message: "sha3-256", - ); -} import "buzz:std"; import "buzz:crypto" as _; From c186745c5a3ee161641c67ed53e0933674db6f13 Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Thu, 23 Jul 2026 18:44:12 +0100 Subject: [PATCH 31/39] Update assertions to use 'message' parameter --- tests/behavior/crypto.buzz | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/tests/behavior/crypto.buzz b/tests/behavior/crypto.buzz index 40f8e301..b72da5fb 100644 --- a/tests/behavior/crypto.buzz +++ b/tests/behavior/crypto.buzz @@ -1,4 +1,3 @@ - import "buzz:std"; import "buzz:crypto" as _; @@ -33,48 +32,47 @@ test "hash" { test "randomBytes returns correct length" { final len = 16; final bytes = randomBytes(len); - std\assert(bytes.len() == len, "randomBytes should return a string of the requested length"); + std\assert(bytes.len() == len, message: "randomBytes should return a string of the requested length"); } test "randomBytes returns different values" { final b1 = randomBytes(8); final b2 = randomBytes(8); - std\assert(b1 != b2, "randomBytes should return different values"); + std\assert(b1 != b2, message: "randomBytes should return different values"); } test "argon2 hashes and verifies" { final password = "my-secure-password"; final hash = argon2(password) ! { - std\assert(false, "argon2 failed: {}", .{error}); + std\assert(false, message: "argon2 failed: {}", .{error}); return; }; final valid = verifyArgon2(password, hash) ! { - std\assert(false, "verifyArgon2 failed: {}", .{error}); + std\assert(false, message: "verifyArgon2 failed: {}", .{error}); return; }; - std\assert(valid, "argon2 verification should succeed for correct password"); + std\assert(valid, message: "argon2 verification should succeed for correct password"); } test "argon2 fails for wrong password" { final password = "my-secure-password"; final wrong = "wrong-password"; final hash = argon2(password) ! { - std\assert(false, "argon2 failed: {}", .{error}); + std\assert(false, message: "argon2 failed: {}", .{error}); return; }; final valid = verifyArgon2(wrong, hash) ! { - std\assert(false, "verifyArgon2 failed: {}", .{error}); + std\assert(false, message: "verifyArgon2 failed: {}", .{error}); return; }; - std\assert(!valid, "argon2 verification should fail for wrong password"); + std\assert(!valid, message: "argon2 verification should fail for wrong password"); } test "argon2 handles invalid hash" { final result = verifyArgon2("password", "invalid-hash"); if (result -> _) { - std\assert(false, "verifyArgon2 should fail for invalid hash"); + std\assert(false, message: "verifyArgon2 should fail for invalid hash"); } else { // Expected error – test passes } } - From 18c4e540b3afa5cdf63693a6408a6fee1513dfdf Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Thu, 23 Jul 2026 18:51:12 +0100 Subject: [PATCH 32/39] Handle errors in argon2 hashing and verification tests --- tests/behavior/crypto.buzz | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/behavior/crypto.buzz b/tests/behavior/crypto.buzz index b72da5fb..fe4b6b4e 100644 --- a/tests/behavior/crypto.buzz +++ b/tests/behavior/crypto.buzz @@ -43,12 +43,12 @@ test "randomBytes returns different values" { test "argon2 hashes and verifies" { final password = "my-secure-password"; - final hash = argon2(password) ! { - std\assert(false, message: "argon2 failed: {}", .{error}); + final hash = argon2(password) catch { + std\assert(false, message: "argon2 failed"); return; }; - final valid = verifyArgon2(password, hash) ! { - std\assert(false, message: "verifyArgon2 failed: {}", .{error}); + final valid = verifyArgon2(password, hash) catch { + std\assert(false, message: "verifyArgon2 failed"); return; }; std\assert(valid, message: "argon2 verification should succeed for correct password"); @@ -57,12 +57,12 @@ test "argon2 hashes and verifies" { test "argon2 fails for wrong password" { final password = "my-secure-password"; final wrong = "wrong-password"; - final hash = argon2(password) ! { - std\assert(false, message: "argon2 failed: {}", .{error}); + final hash = argon2(password) catch { + std\assert(false, message: "argon2 failed"); return; }; - final valid = verifyArgon2(wrong, hash) ! { - std\assert(false, message: "verifyArgon2 failed: {}", .{error}); + final valid = verifyArgon2(wrong, hash) catch { + std\assert(false, message: "verifyArgon2 failed"); return; }; std\assert(!valid, message: "argon2 verification should fail for wrong password"); From 3200fe651b553ad7c7b2c818846a4dd8e3e8d6e0 Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Thu, 23 Jul 2026 19:09:34 +0100 Subject: [PATCH 33/39] Refactor assertions for clarity in crypto tests --- tests/behavior/crypto.buzz | 45 ++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/tests/behavior/crypto.buzz b/tests/behavior/crypto.buzz index fe4b6b4e..425fa80c 100644 --- a/tests/behavior/crypto.buzz +++ b/tests/behavior/crypto.buzz @@ -32,46 +32,73 @@ test "hash" { test "randomBytes returns correct length" { final len = 16; final bytes = randomBytes(len); - std\assert(bytes.len() == len, message: "randomBytes should return a string of the requested length"); + std\assert( + bytes.len() == len, + message: "randomBytes should return a string of the requested length" + ); } test "randomBytes returns different values" { final b1 = randomBytes(8); final b2 = randomBytes(8); - std\assert(b1 != b2, message: "randomBytes should return different values"); + std\assert( + b1 != b2, + message: "randomBytes should return different values" + ); } test "argon2 hashes and verifies" { final password = "my-secure-password"; final hash = argon2(password) catch { - std\assert(false, message: "argon2 failed"); + std\assert( + false, + message: "argon2 failed" + ); return; }; final valid = verifyArgon2(password, hash) catch { - std\assert(false, message: "verifyArgon2 failed"); + std\assert( + false, + message: "verifyArgon2 failed" + ); return; }; - std\assert(valid, message: "argon2 verification should succeed for correct password"); + std\assert( + valid, + message: "argon2 verification should succeed for correct password" + ); } test "argon2 fails for wrong password" { final password = "my-secure-password"; final wrong = "wrong-password"; final hash = argon2(password) catch { - std\assert(false, message: "argon2 failed"); + std\assert( + false, + message: "argon2 failed" + ); return; }; final valid = verifyArgon2(wrong, hash) catch { - std\assert(false, message: "verifyArgon2 failed"); + std\assert( + false, + message: "verifyArgon2 failed" + ); return; }; - std\assert(!valid, message: "argon2 verification should fail for wrong password"); + std\assert( + !valid, + message: "argon2 verification should fail for wrong password" + ); } test "argon2 handles invalid hash" { final result = verifyArgon2("password", "invalid-hash"); if (result -> _) { - std\assert(false, message: "verifyArgon2 should fail for invalid hash"); + std\assert( + false, + message: "verifyArgon2 should fail for invalid hash" + ); } else { // Expected error – test passes } From f4e14ffdf60072cd11cd44fad35b96ead25cd2ba Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Thu, 23 Jul 2026 20:32:46 +0100 Subject: [PATCH 34/39] Update error handling in argon2 tests --- tests/behavior/crypto.buzz | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/behavior/crypto.buzz b/tests/behavior/crypto.buzz index 425fa80c..b9f9e0a5 100644 --- a/tests/behavior/crypto.buzz +++ b/tests/behavior/crypto.buzz @@ -49,14 +49,14 @@ test "randomBytes returns different values" { test "argon2 hashes and verifies" { final password = "my-secure-password"; - final hash = argon2(password) catch { + final hash = argon2(password) catch from { std\assert( false, message: "argon2 failed" ); return; }; - final valid = verifyArgon2(password, hash) catch { + final valid = verifyArgon2(password, hash) catch from { std\assert( false, message: "verifyArgon2 failed" @@ -72,14 +72,14 @@ test "argon2 hashes and verifies" { test "argon2 fails for wrong password" { final password = "my-secure-password"; final wrong = "wrong-password"; - final hash = argon2(password) catch { + final hash = argon2(password) catch from { std\assert( false, message: "argon2 failed" ); return; }; - final valid = verifyArgon2(wrong, hash) catch { + final valid = verifyArgon2(wrong, hash) catch from { std\assert( false, message: "verifyArgon2 failed" From 898a6b4e139ae20f245e78cd8972b2b87f0db3da Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Thu, 23 Jul 2026 20:46:12 +0100 Subject: [PATCH 35/39] Enhance verifyArgon2 with InvalidArgumentError Added error handling for invalid arguments in verifyArgon2 function. --- src/lib/crypto.buzz | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/crypto.buzz b/src/lib/crypto.buzz index c30e19f5..8c91178c 100644 --- a/src/lib/crypto.buzz +++ b/src/lib/crypto.buzz @@ -40,4 +40,4 @@ export extern fun argon2(password: str) > str; /// @param password The password to verify /// @param hash The encoded hash string from argon2id() /// @return true if the password matches the hash -export extern fun verifyArgon2(password: str, hash: str) > bool; +export extern fun verifyArgon2(password: str, hash: str) > bool !> errors\InvalidArgumentError; From a3f530bd0cbdc8d12575bf8b71f975549d9e3b9d Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Thu, 23 Jul 2026 20:54:11 +0100 Subject: [PATCH 36/39] Add AuthenticationFailed error object --- src/lib/errors.buzz | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lib/errors.buzz b/src/lib/errors.buzz index 413b84f3..6df0ea05 100644 --- a/src/lib/errors.buzz +++ b/src/lib/errors.buzz @@ -187,3 +187,8 @@ export object UnderflowError { export object UnexpectedError { message: str = "UnexpectedError", } + +/// Error raised when an authentication process failed +export object AuthenticationFailed { + message: str = "AuthenticationFailed", +} From e6fb53fed5a5dd775ed40c8a625c123c4e1ad3f6 Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Thu, 23 Jul 2026 20:57:41 +0100 Subject: [PATCH 37/39] Update error handling for Argon2 functions --- src/lib/crypto.buzz | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/crypto.buzz b/src/lib/crypto.buzz index 8c91178c..f4865d46 100644 --- a/src/lib/crypto.buzz +++ b/src/lib/crypto.buzz @@ -34,10 +34,10 @@ export extern fun randomBytes(len: int) > str; /// Hash a password using Argon2id /// @param password The password to hash /// @return The encoded hash string -export extern fun argon2(password: str) > str; +export extern fun argon2(password: str) > str !> errors\AuthenticationFailed; /// Verify a password against an Argon2id hash /// @param password The password to verify /// @param hash The encoded hash string from argon2id() /// @return true if the password matches the hash -export extern fun verifyArgon2(password: str, hash: str) > bool !> errors\InvalidArgumentError; +export extern fun verifyArgon2(password: str, hash: str) > bool !> errors\AuthenticationFailed; From 36925151f472fee3939ebdb381da0e6d1dfb738b Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Thu, 23 Jul 2026 21:03:38 +0100 Subject: [PATCH 38/39] Delete argon2 invalid hash test case Removed test for argon2 handling of invalid hash. --- tests/behavior/crypto.buzz | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/tests/behavior/crypto.buzz b/tests/behavior/crypto.buzz index b9f9e0a5..ceb1a4a1 100644 --- a/tests/behavior/crypto.buzz +++ b/tests/behavior/crypto.buzz @@ -91,15 +91,3 @@ test "argon2 fails for wrong password" { message: "argon2 verification should fail for wrong password" ); } - -test "argon2 handles invalid hash" { - final result = verifyArgon2("password", "invalid-hash"); - if (result -> _) { - std\assert( - false, - message: "verifyArgon2 should fail for invalid hash" - ); - } else { - // Expected error – test passes - } -} From d5b8686d350bbb192baaa3b68a40b13d6e824554 Mon Sep 17 00:00:00 2001 From: ZenDrx Date: Sun, 2 Aug 2026 15:58:13 +0100 Subject: [PATCH 39/39] Refactor Argon2 parameters for password hashing --- src/lib/buzz_crypto.zig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib/buzz_crypto.zig b/src/lib/buzz_crypto.zig index 2091100b..3c8ef35e 100644 --- a/src/lib/buzz_crypto.zig +++ b/src/lib/buzz_crypto.zig @@ -118,9 +118,10 @@ pub export fn argon2(ctx: *api.NativeCtx) callconv(.c) c_int { const password = pass_ptr.?[0..pass_len]; var hash_buf: [256]u8 = undefined; const io = ctx.getIo(); + const params = std.crypto.pwhash.argon2.Params.owasp_2id; const hash_r = std.crypto.pwhash.argon2.strHash(password, .{ .allocator = api.VM.allocator, - .params = .{ .t = 2, .m = 19 * 1024, .p = 1 }, + .params = params, }, &hash_buf, io) catch { ctx.vm.pushError("errors.AuthenticationFailed", "argon2 failed"); return -1;