From 74d8ceb9d30717b0134b9f22ac96ea8dca1801d5 Mon Sep 17 00:00:00 2001 From: gorusys Date: Thu, 2 Apr 2026 18:58:07 +0200 Subject: [PATCH 1/7] test: add negative BLS verify and FAV cases --- src/state_transition/utils/bls.zig | 55 +++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/src/state_transition/utils/bls.zig b/src/state_transition/utils/bls.zig index c8fa721fe..288f03a9e 100644 --- a/src/state_transition/utils/bls.zig +++ b/src/state_transition/utils/bls.zig @@ -22,6 +22,7 @@ pub fn verify(msg: []const u8, pk: *const PublicKey, sig: *const Signature, in_p try sig.verify(sig_groupcheck, msg, DST, null, pk, pk_validate); } +/// `msg` must be at least 32 bytes; only the first 32 are passed to fast aggregate verification. pub fn fastAggregateVerify(msg: []const u8, pks: []const PublicKey, sig: *const Signature, in_pk_validate: ?bool, in_sigs_group_check: ?bool) !bool { var pairing_buf: [bls.Pairing.sizeOf()]u8 align(bls.Pairing.buf_align) = undefined; @@ -30,7 +31,6 @@ pub fn fastAggregateVerify(msg: []const u8, pks: []const PublicKey, sig: *const return sig.fastAggregateVerify(sigs_groupcheck, &pairing_buf, msg[0..32], DST, pks, pks_validate) catch return false; } -// TODO: unit tests test "bls - sanity" { const ikm: [32]u8 = [_]u8{ 0x93, 0xad, 0x7e, 0x65, 0xde, 0xad, 0x05, 0x2a, 0x08, 0x3a, @@ -49,3 +49,56 @@ test "bls - sanity" { const result = try fastAggregateVerify(&msg, pks_slice[0..], &sig, null, null); try std.testing.expect(result); } + +test "bls - verify fails on wrong message" { + const ikm: [32]u8 = [_]u8{ + 0x93, 0xad, 0x7e, 0x65, 0xde, 0xad, 0x05, 0x2a, 0x08, 0x3a, + 0x91, 0x0c, 0x8b, 0x72, 0x85, 0x91, 0x46, 0x4c, 0xca, 0x56, + 0x60, 0x5b, 0xb0, 0x56, 0xed, 0xfe, 0x2b, 0x60, 0xa6, 0x3c, + 0x48, 0x99, + }; + const sk = try SecretKey.keyGen(ikm[0..], null); + var msg = [_]u8{1} ** 32; + const sig = sign(sk, &msg); + const pk = sk.toPublicKey(); + msg[0] ^= 1; + try std.testing.expectError(bls.BlstError.VerifyFail, verify(&msg, &pk, &sig, null, null)); +} + +test "bls - verify fails on wrong public key" { + const ikm_a: [32]u8 = [_]u8{ + 0x93, 0xad, 0x7e, 0x65, 0xde, 0xad, 0x05, 0x2a, 0x08, 0x3a, + 0x91, 0x0c, 0x8b, 0x72, 0x85, 0x91, 0x46, 0x4c, 0xca, 0x56, + 0x60, 0x5b, 0xb0, 0x56, 0xed, 0xfe, 0x2b, 0x60, 0xa6, 0x3c, + 0x48, 0x99, + }; + const ikm_b: [32]u8 = [_]u8{ + 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, + 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, + }; + const sk_a = try SecretKey.keyGen(ikm_a[0..], null); + const sk_b = try SecretKey.keyGen(ikm_b[0..], null); + const msg = [_]u8{1} ** 32; + const sig = sign(sk_a, &msg); + const pk_b = sk_b.toPublicKey(); + try std.testing.expectError(bls.BlstError.VerifyFail, verify(&msg, &pk_b, &sig, null, null)); +} + +test "bls - fastAggregateVerify false on wrong message" { + const ikm: [32]u8 = [_]u8{ + 0x93, 0xad, 0x7e, 0x65, 0xde, 0xad, 0x05, 0x2a, 0x08, 0x3a, + 0x91, 0x0c, 0x8b, 0x72, 0x85, 0x91, 0x46, 0x4c, 0xca, 0x56, + 0x60, 0x5b, 0xb0, 0x56, 0xed, 0xfe, 0x2b, 0x60, 0xa6, 0x3c, + 0x48, 0x99, + }; + const sk = try SecretKey.keyGen(ikm[0..], null); + var msg = [_]u8{1} ** 32; + const sig = sign(sk, &msg); + const pk = sk.toPublicKey(); + msg[31] ^= 0xff; + var pks = [_]PublicKey{pk}; + const result = try fastAggregateVerify(&msg, pks[0..], &sig, null, null); + try std.testing.expect(!result); +} From 44407ca4a9b65413e66ce81c509b569e3ab5b898 Mon Sep 17 00:00:00 2001 From: gorusys Date: Thu, 2 Apr 2026 19:12:57 +0200 Subject: [PATCH 2/7] chore: wrap fastAggregateVerify msg comment & assert len >= 32 --- src/state_transition/utils/bls.zig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/state_transition/utils/bls.zig b/src/state_transition/utils/bls.zig index 288f03a9e..021b65c34 100644 --- a/src/state_transition/utils/bls.zig +++ b/src/state_transition/utils/bls.zig @@ -22,8 +22,11 @@ pub fn verify(msg: []const u8, pk: *const PublicKey, sig: *const Signature, in_p try sig.verify(sig_groupcheck, msg, DST, null, pk, pk_validate); } -/// `msg` must be at least 32 bytes; only the first 32 are passed to fast aggregate verification. +/// The `msg` must be at least 32 bytes; only the first 32 are passed to +/// fast aggregate verification. pub fn fastAggregateVerify(msg: []const u8, pks: []const PublicKey, sig: *const Signature, in_pk_validate: ?bool, in_sigs_group_check: ?bool) !bool { + std.debug.assert(msg.len >= 32); + var pairing_buf: [bls.Pairing.sizeOf()]u8 align(bls.Pairing.buf_align) = undefined; const sigs_groupcheck = in_sigs_group_check orelse false; From a8550ca4b65af2e46028417db7180521c542110f Mon Sep 17 00:00:00 2001 From: gorusys Date: Fri, 3 Apr 2026 13:11:49 +0200 Subject: [PATCH 3/7] test: add positive BLS utils coverage --- src/state_transition/utils/bls.zig | 46 ++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/state_transition/utils/bls.zig b/src/state_transition/utils/bls.zig index 021b65c34..3d68a9d95 100644 --- a/src/state_transition/utils/bls.zig +++ b/src/state_transition/utils/bls.zig @@ -53,6 +53,52 @@ test "bls - sanity" { try std.testing.expect(result); } +test "bls - sign and verify round trip variable-length message" { + const ikm: [32]u8 = [_]u8{ + 0x93, 0xad, 0x7e, 0x65, 0xde, 0xad, 0x05, 0x2a, 0x08, 0x3a, + 0x91, 0x0c, 0x8b, 0x72, 0x85, 0x91, 0x46, 0x4c, 0xca, 0x56, + 0x60, 0x5b, 0xb0, 0x56, 0xed, 0xfe, 0x2b, 0x60, 0xa6, 0x3c, + 0x48, 0x99, + }; + const sk = try SecretKey.keyGen(ikm[0..], null); + const msg = "ethereum consensus"; + const sig = sign(sk, msg); + const pk = sk.toPublicKey(); + try verify(msg, &pk, &sig, null, null); +} + +test "bls - verify with pubkey and signature subgroup checks" { + const ikm: [32]u8 = [_]u8{ + 0x93, 0xad, 0x7e, 0x65, 0xde, 0xad, 0x05, 0x2a, 0x08, 0x3a, + 0x91, 0x0c, 0x8b, 0x72, 0x85, 0x91, 0x46, 0x4c, 0xca, 0x56, + 0x60, 0x5b, 0xb0, 0x56, 0xed, 0xfe, 0x2b, 0x60, 0xa6, 0x3c, + 0x48, 0x99, + }; + const sk = try SecretKey.keyGen(ikm[0..], null); + const msg = [_]u8{0xab} ** 32; + const sig = sign(sk, &msg); + const pk = sk.toPublicKey(); + try verify(&msg, &pk, &sig, true, true); +} + +test "bls - fastAggregateVerify uses only first 32 bytes of longer buffer" { + const ikm: [32]u8 = [_]u8{ + 0x93, 0xad, 0x7e, 0x65, 0xde, 0xad, 0x05, 0x2a, 0x08, 0x3a, + 0x91, 0x0c, 0x8b, 0x72, 0x85, 0x91, 0x46, 0x4c, 0xca, 0x56, + 0x60, 0x5b, 0xb0, 0x56, 0xed, 0xfe, 0x2b, 0x60, 0xa6, 0x3c, + 0x48, 0x99, + }; + const sk = try SecretKey.keyGen(ikm[0..], null); + var msg64: [64]u8 = undefined; + @memset(msg64[32..], 0xcd); + @memset(msg64[0..32], 0x42); + const sig = sign(sk, msg64[0..32]); + const pk = sk.toPublicKey(); + var pks = [_]PublicKey{pk}; + const ok = try fastAggregateVerify(&msg64, pks[0..], &sig, null, null); + try std.testing.expect(ok); +} + test "bls - verify fails on wrong message" { const ikm: [32]u8 = [_]u8{ 0x93, 0xad, 0x7e, 0x65, 0xde, 0xad, 0x05, 0x2a, 0x08, 0x3a, From 94e805d9e3319a014505aab7d41abea28836a35d Mon Sep 17 00:00:00 2001 From: gorusys Date: Wed, 8 Apr 2026 02:59:18 +0200 Subject: [PATCH 4/7] test(bls): clarify variable names and use expectEqual --- src/state_transition/utils/bls.zig | 130 ++++++++++++++--------------- 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/src/state_transition/utils/bls.zig b/src/state_transition/utils/bls.zig index 3d68a9d95..cd5815bff 100644 --- a/src/state_transition/utils/bls.zig +++ b/src/state_transition/utils/bls.zig @@ -7,8 +7,8 @@ const SecretKey = bls.SecretKey; /// See https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#bls-signatures const DST: []const u8 = "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_"; -pub fn sign(secret_key: SecretKey, msg: []const u8) Signature { - return secret_key.sign(msg, DST, null); +pub fn sign(secret_key: SecretKey, message: []const u8) Signature { + return secret_key.sign(message, DST, null); } /// Verify a signature against a message and public key. @@ -16,138 +16,138 @@ pub fn sign(secret_key: SecretKey, msg: []const u8) Signature { /// If `pk_validate` is `true`, the public key will be infinity and group checked. /// /// If `sig_groupcheck` is `true`, the signature will be group checked. -pub fn verify(msg: []const u8, pk: *const PublicKey, sig: *const Signature, in_pk_validate: ?bool, in_sig_groupcheck: ?bool) bls.BlstError!void { +pub fn verify(message: []const u8, public_key: *const PublicKey, signature: *const Signature, in_pk_validate: ?bool, in_sig_groupcheck: ?bool) bls.BlstError!void { const sig_groupcheck = in_sig_groupcheck orelse false; const pk_validate = in_pk_validate orelse false; - try sig.verify(sig_groupcheck, msg, DST, null, pk, pk_validate); + try signature.verify(sig_groupcheck, message, DST, null, public_key, pk_validate); } -/// The `msg` must be at least 32 bytes; only the first 32 are passed to +/// The `message` must be at least 32 bytes; only the first 32 are passed to /// fast aggregate verification. -pub fn fastAggregateVerify(msg: []const u8, pks: []const PublicKey, sig: *const Signature, in_pk_validate: ?bool, in_sigs_group_check: ?bool) !bool { - std.debug.assert(msg.len >= 32); +pub fn fastAggregateVerify(message: []const u8, public_keys: []const PublicKey, signature: *const Signature, in_pk_validate: ?bool, in_sigs_group_check: ?bool) !bool { + std.debug.assert(message.len >= 32); var pairing_buf: [bls.Pairing.sizeOf()]u8 align(bls.Pairing.buf_align) = undefined; const sigs_groupcheck = in_sigs_group_check orelse false; - const pks_validate = in_pk_validate orelse false; - return sig.fastAggregateVerify(sigs_groupcheck, &pairing_buf, msg[0..32], DST, pks, pks_validate) catch return false; + const public_keys_validate = in_pk_validate orelse false; + return signature.fastAggregateVerify(sigs_groupcheck, &pairing_buf, message[0..32], DST, public_keys, public_keys_validate) catch return false; } test "bls - sanity" { - const ikm: [32]u8 = [_]u8{ + const input_key_material: [32]u8 = [_]u8{ 0x93, 0xad, 0x7e, 0x65, 0xde, 0xad, 0x05, 0x2a, 0x08, 0x3a, 0x91, 0x0c, 0x8b, 0x72, 0x85, 0x91, 0x46, 0x4c, 0xca, 0x56, 0x60, 0x5b, 0xb0, 0x56, 0xed, 0xfe, 0x2b, 0x60, 0xa6, 0x3c, 0x48, 0x99, }; - const sk = try SecretKey.keyGen(ikm[0..], null); - const msg = [_]u8{1} ** 32; - const sig = sign(sk, &msg); - const pk = sk.toPublicKey(); - try verify(&msg, &pk, &sig, null, null); + const secret_key = try SecretKey.keyGen(input_key_material[0..], null); + const message = [_]u8{1} ** 32; + const signature = sign(secret_key, &message); + const public_key = secret_key.toPublicKey(); + try verify(&message, &public_key, &signature, null, null); - var pks = [_]PublicKey{pk}; - var pks_slice: []const PublicKey = pks[0..1]; - const result = try fastAggregateVerify(&msg, pks_slice[0..], &sig, null, null); - try std.testing.expect(result); + var public_keys = [_]PublicKey{public_key}; + var public_keys_slice: []const PublicKey = public_keys[0..1]; + const fast_aggregate_verified = try fastAggregateVerify(&message, public_keys_slice[0..], &signature, null, null); + try std.testing.expectEqual(true, fast_aggregate_verified); } test "bls - sign and verify round trip variable-length message" { - const ikm: [32]u8 = [_]u8{ + const input_key_material: [32]u8 = [_]u8{ 0x93, 0xad, 0x7e, 0x65, 0xde, 0xad, 0x05, 0x2a, 0x08, 0x3a, 0x91, 0x0c, 0x8b, 0x72, 0x85, 0x91, 0x46, 0x4c, 0xca, 0x56, 0x60, 0x5b, 0xb0, 0x56, 0xed, 0xfe, 0x2b, 0x60, 0xa6, 0x3c, 0x48, 0x99, }; - const sk = try SecretKey.keyGen(ikm[0..], null); - const msg = "ethereum consensus"; - const sig = sign(sk, msg); - const pk = sk.toPublicKey(); - try verify(msg, &pk, &sig, null, null); + const secret_key = try SecretKey.keyGen(input_key_material[0..], null); + const message = "ethereum consensus"; + const signature = sign(secret_key, message); + const public_key = secret_key.toPublicKey(); + try verify(message, &public_key, &signature, null, null); } test "bls - verify with pubkey and signature subgroup checks" { - const ikm: [32]u8 = [_]u8{ + const input_key_material: [32]u8 = [_]u8{ 0x93, 0xad, 0x7e, 0x65, 0xde, 0xad, 0x05, 0x2a, 0x08, 0x3a, 0x91, 0x0c, 0x8b, 0x72, 0x85, 0x91, 0x46, 0x4c, 0xca, 0x56, 0x60, 0x5b, 0xb0, 0x56, 0xed, 0xfe, 0x2b, 0x60, 0xa6, 0x3c, 0x48, 0x99, }; - const sk = try SecretKey.keyGen(ikm[0..], null); - const msg = [_]u8{0xab} ** 32; - const sig = sign(sk, &msg); - const pk = sk.toPublicKey(); - try verify(&msg, &pk, &sig, true, true); + const secret_key = try SecretKey.keyGen(input_key_material[0..], null); + const message = [_]u8{0xab} ** 32; + const signature = sign(secret_key, &message); + const public_key = secret_key.toPublicKey(); + try verify(&message, &public_key, &signature, true, true); } test "bls - fastAggregateVerify uses only first 32 bytes of longer buffer" { - const ikm: [32]u8 = [_]u8{ + const input_key_material: [32]u8 = [_]u8{ 0x93, 0xad, 0x7e, 0x65, 0xde, 0xad, 0x05, 0x2a, 0x08, 0x3a, 0x91, 0x0c, 0x8b, 0x72, 0x85, 0x91, 0x46, 0x4c, 0xca, 0x56, 0x60, 0x5b, 0xb0, 0x56, 0xed, 0xfe, 0x2b, 0x60, 0xa6, 0x3c, 0x48, 0x99, }; - const sk = try SecretKey.keyGen(ikm[0..], null); - var msg64: [64]u8 = undefined; - @memset(msg64[32..], 0xcd); - @memset(msg64[0..32], 0x42); - const sig = sign(sk, msg64[0..32]); - const pk = sk.toPublicKey(); - var pks = [_]PublicKey{pk}; - const ok = try fastAggregateVerify(&msg64, pks[0..], &sig, null, null); - try std.testing.expect(ok); + const secret_key = try SecretKey.keyGen(input_key_material[0..], null); + var message_64: [64]u8 = undefined; + @memset(message_64[32..], 0xcd); + @memset(message_64[0..32], 0x42); + const signature = sign(secret_key, message_64[0..32]); + const public_key = secret_key.toPublicKey(); + var public_keys = [_]PublicKey{public_key}; + const fast_aggregate_verified = try fastAggregateVerify(&message_64, public_keys[0..], &signature, null, null); + try std.testing.expectEqual(true, fast_aggregate_verified); } test "bls - verify fails on wrong message" { - const ikm: [32]u8 = [_]u8{ + const input_key_material: [32]u8 = [_]u8{ 0x93, 0xad, 0x7e, 0x65, 0xde, 0xad, 0x05, 0x2a, 0x08, 0x3a, 0x91, 0x0c, 0x8b, 0x72, 0x85, 0x91, 0x46, 0x4c, 0xca, 0x56, 0x60, 0x5b, 0xb0, 0x56, 0xed, 0xfe, 0x2b, 0x60, 0xa6, 0x3c, 0x48, 0x99, }; - const sk = try SecretKey.keyGen(ikm[0..], null); - var msg = [_]u8{1} ** 32; - const sig = sign(sk, &msg); - const pk = sk.toPublicKey(); - msg[0] ^= 1; - try std.testing.expectError(bls.BlstError.VerifyFail, verify(&msg, &pk, &sig, null, null)); + const secret_key = try SecretKey.keyGen(input_key_material[0..], null); + var message = [_]u8{1} ** 32; + const signature = sign(secret_key, &message); + const public_key = secret_key.toPublicKey(); + message[0] ^= 1; + try std.testing.expectError(bls.BlstError.VerifyFail, verify(&message, &public_key, &signature, null, null)); } test "bls - verify fails on wrong public key" { - const ikm_a: [32]u8 = [_]u8{ + const input_key_material_a: [32]u8 = [_]u8{ 0x93, 0xad, 0x7e, 0x65, 0xde, 0xad, 0x05, 0x2a, 0x08, 0x3a, 0x91, 0x0c, 0x8b, 0x72, 0x85, 0x91, 0x46, 0x4c, 0xca, 0x56, 0x60, 0x5b, 0xb0, 0x56, 0xed, 0xfe, 0x2b, 0x60, 0xa6, 0x3c, 0x48, 0x99, }; - const ikm_b: [32]u8 = [_]u8{ + const input_key_material_b: [32]u8 = [_]u8{ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, }; - const sk_a = try SecretKey.keyGen(ikm_a[0..], null); - const sk_b = try SecretKey.keyGen(ikm_b[0..], null); - const msg = [_]u8{1} ** 32; - const sig = sign(sk_a, &msg); - const pk_b = sk_b.toPublicKey(); - try std.testing.expectError(bls.BlstError.VerifyFail, verify(&msg, &pk_b, &sig, null, null)); + const secret_key_a = try SecretKey.keyGen(input_key_material_a[0..], null); + const secret_key_b = try SecretKey.keyGen(input_key_material_b[0..], null); + const message = [_]u8{1} ** 32; + const signature = sign(secret_key_a, &message); + const public_key_b = secret_key_b.toPublicKey(); + try std.testing.expectError(bls.BlstError.VerifyFail, verify(&message, &public_key_b, &signature, null, null)); } test "bls - fastAggregateVerify false on wrong message" { - const ikm: [32]u8 = [_]u8{ + const input_key_material: [32]u8 = [_]u8{ 0x93, 0xad, 0x7e, 0x65, 0xde, 0xad, 0x05, 0x2a, 0x08, 0x3a, 0x91, 0x0c, 0x8b, 0x72, 0x85, 0x91, 0x46, 0x4c, 0xca, 0x56, 0x60, 0x5b, 0xb0, 0x56, 0xed, 0xfe, 0x2b, 0x60, 0xa6, 0x3c, 0x48, 0x99, }; - const sk = try SecretKey.keyGen(ikm[0..], null); - var msg = [_]u8{1} ** 32; - const sig = sign(sk, &msg); - const pk = sk.toPublicKey(); - msg[31] ^= 0xff; - var pks = [_]PublicKey{pk}; - const result = try fastAggregateVerify(&msg, pks[0..], &sig, null, null); - try std.testing.expect(!result); + const secret_key = try SecretKey.keyGen(input_key_material[0..], null); + var message = [_]u8{1} ** 32; + const signature = sign(secret_key, &message); + const public_key = secret_key.toPublicKey(); + message[31] ^= 0xff; + var public_keys = [_]PublicKey{public_key}; + const fast_aggregate_verified = try fastAggregateVerify(&message, public_keys[0..], &signature, null, null); + try std.testing.expectEqual(false, fast_aggregate_verified); } From 5e1eb80d9044fbf8ebf6307fbef50b11aa9af40d Mon Sep 17 00:00:00 2001 From: gorusys Date: Wed, 8 Apr 2026 03:16:59 +0200 Subject: [PATCH 5/7] chore(bls): drop redundant slice in bls sanity test --- src/state_transition/utils/bls.zig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/state_transition/utils/bls.zig b/src/state_transition/utils/bls.zig index cd5815bff..7c7d25c0c 100644 --- a/src/state_transition/utils/bls.zig +++ b/src/state_transition/utils/bls.zig @@ -47,9 +47,9 @@ test "bls - sanity" { const public_key = secret_key.toPublicKey(); try verify(&message, &public_key, &signature, null, null); - var public_keys = [_]PublicKey{public_key}; - var public_keys_slice: []const PublicKey = public_keys[0..1]; - const fast_aggregate_verified = try fastAggregateVerify(&message, public_keys_slice[0..], &signature, null, null); + const public_keys = [_]PublicKey{public_key}; + const public_keys_slice: []const PublicKey = public_keys[0..1]; + const fast_aggregate_verified = try fastAggregateVerify(&message, public_keys_slice, &signature, null, null); try std.testing.expectEqual(true, fast_aggregate_verified); } From 594cfa77c7bd698f381c4333ed8fcaeede7b3887 Mon Sep 17 00:00:00 2001 From: gorusys Date: Wed, 8 Apr 2026 13:59:51 +0200 Subject: [PATCH 6/7] chore(bls): align function parameter names with doc comments --- src/state_transition/utils/bls.zig | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/state_transition/utils/bls.zig b/src/state_transition/utils/bls.zig index 7c7d25c0c..8a657ee4e 100644 --- a/src/state_transition/utils/bls.zig +++ b/src/state_transition/utils/bls.zig @@ -16,22 +16,22 @@ pub fn sign(secret_key: SecretKey, message: []const u8) Signature { /// If `pk_validate` is `true`, the public key will be infinity and group checked. /// /// If `sig_groupcheck` is `true`, the signature will be group checked. -pub fn verify(message: []const u8, public_key: *const PublicKey, signature: *const Signature, in_pk_validate: ?bool, in_sig_groupcheck: ?bool) bls.BlstError!void { - const sig_groupcheck = in_sig_groupcheck orelse false; - const pk_validate = in_pk_validate orelse false; - try signature.verify(sig_groupcheck, message, DST, null, public_key, pk_validate); +pub fn verify(message: []const u8, public_key: *const PublicKey, signature: *const Signature, pk_validate: ?bool, sig_groupcheck: ?bool) bls.BlstError!void { + const sig_groupcheck_flag = sig_groupcheck orelse false; + const pk_validate_flag = pk_validate orelse false; + try signature.verify(sig_groupcheck_flag, message, DST, null, public_key, pk_validate_flag); } /// The `message` must be at least 32 bytes; only the first 32 are passed to /// fast aggregate verification. -pub fn fastAggregateVerify(message: []const u8, public_keys: []const PublicKey, signature: *const Signature, in_pk_validate: ?bool, in_sigs_group_check: ?bool) !bool { +pub fn fastAggregateVerify(message: []const u8, public_keys: []const PublicKey, signature: *const Signature, pk_validate: ?bool, sig_groupcheck: ?bool) !bool { std.debug.assert(message.len >= 32); var pairing_buf: [bls.Pairing.sizeOf()]u8 align(bls.Pairing.buf_align) = undefined; - const sigs_groupcheck = in_sigs_group_check orelse false; - const public_keys_validate = in_pk_validate orelse false; - return signature.fastAggregateVerify(sigs_groupcheck, &pairing_buf, message[0..32], DST, public_keys, public_keys_validate) catch return false; + const sig_groupcheck_flag = sig_groupcheck orelse false; + const pk_validate_flag = pk_validate orelse false; + return signature.fastAggregateVerify(sig_groupcheck_flag, &pairing_buf, message[0..32], DST, public_keys, pk_validate_flag) catch return false; } test "bls - sanity" { From 9cafa2dcf252ad93b88635697a8a391c00eb59a7 Mon Sep 17 00:00:00 2001 From: gorusys Date: Mon, 13 Apr 2026 20:02:18 +0200 Subject: [PATCH 7/7] refactor: deduplicate test key material in bls.zig tests --- src/state_transition/utils/bls.zig | 73 ++++++++---------------------- 1 file changed, 19 insertions(+), 54 deletions(-) diff --git a/src/state_transition/utils/bls.zig b/src/state_transition/utils/bls.zig index 8a657ee4e..3f72421df 100644 --- a/src/state_transition/utils/bls.zig +++ b/src/state_transition/utils/bls.zig @@ -34,14 +34,21 @@ pub fn fastAggregateVerify(message: []const u8, public_keys: []const PublicKey, return signature.fastAggregateVerify(sig_groupcheck_flag, &pairing_buf, message[0..32], DST, public_keys, pk_validate_flag) catch return false; } +const input_key_material_a: [32]u8 = [_]u8{ + 0x93, 0xad, 0x7e, 0x65, 0xde, 0xad, 0x05, 0x2a, 0x08, 0x3a, + 0x91, 0x0c, 0x8b, 0x72, 0x85, 0x91, 0x46, 0x4c, 0xca, 0x56, + 0x60, 0x5b, 0xb0, 0x56, 0xed, 0xfe, 0x2b, 0x60, 0xa6, 0x3c, + 0x48, 0x99, +}; +const input_key_material_b: [32]u8 = [_]u8{ + 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, + 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, +}; + test "bls - sanity" { - const input_key_material: [32]u8 = [_]u8{ - 0x93, 0xad, 0x7e, 0x65, 0xde, 0xad, 0x05, 0x2a, 0x08, 0x3a, - 0x91, 0x0c, 0x8b, 0x72, 0x85, 0x91, 0x46, 0x4c, 0xca, 0x56, - 0x60, 0x5b, 0xb0, 0x56, 0xed, 0xfe, 0x2b, 0x60, 0xa6, 0x3c, - 0x48, 0x99, - }; - const secret_key = try SecretKey.keyGen(input_key_material[0..], null); + const secret_key = try SecretKey.keyGen(input_key_material_a[0..], null); const message = [_]u8{1} ** 32; const signature = sign(secret_key, &message); const public_key = secret_key.toPublicKey(); @@ -54,13 +61,7 @@ test "bls - sanity" { } test "bls - sign and verify round trip variable-length message" { - const input_key_material: [32]u8 = [_]u8{ - 0x93, 0xad, 0x7e, 0x65, 0xde, 0xad, 0x05, 0x2a, 0x08, 0x3a, - 0x91, 0x0c, 0x8b, 0x72, 0x85, 0x91, 0x46, 0x4c, 0xca, 0x56, - 0x60, 0x5b, 0xb0, 0x56, 0xed, 0xfe, 0x2b, 0x60, 0xa6, 0x3c, - 0x48, 0x99, - }; - const secret_key = try SecretKey.keyGen(input_key_material[0..], null); + const secret_key = try SecretKey.keyGen(input_key_material_a[0..], null); const message = "ethereum consensus"; const signature = sign(secret_key, message); const public_key = secret_key.toPublicKey(); @@ -68,13 +69,7 @@ test "bls - sign and verify round trip variable-length message" { } test "bls - verify with pubkey and signature subgroup checks" { - const input_key_material: [32]u8 = [_]u8{ - 0x93, 0xad, 0x7e, 0x65, 0xde, 0xad, 0x05, 0x2a, 0x08, 0x3a, - 0x91, 0x0c, 0x8b, 0x72, 0x85, 0x91, 0x46, 0x4c, 0xca, 0x56, - 0x60, 0x5b, 0xb0, 0x56, 0xed, 0xfe, 0x2b, 0x60, 0xa6, 0x3c, - 0x48, 0x99, - }; - const secret_key = try SecretKey.keyGen(input_key_material[0..], null); + const secret_key = try SecretKey.keyGen(input_key_material_a[0..], null); const message = [_]u8{0xab} ** 32; const signature = sign(secret_key, &message); const public_key = secret_key.toPublicKey(); @@ -82,13 +77,7 @@ test "bls - verify with pubkey and signature subgroup checks" { } test "bls - fastAggregateVerify uses only first 32 bytes of longer buffer" { - const input_key_material: [32]u8 = [_]u8{ - 0x93, 0xad, 0x7e, 0x65, 0xde, 0xad, 0x05, 0x2a, 0x08, 0x3a, - 0x91, 0x0c, 0x8b, 0x72, 0x85, 0x91, 0x46, 0x4c, 0xca, 0x56, - 0x60, 0x5b, 0xb0, 0x56, 0xed, 0xfe, 0x2b, 0x60, 0xa6, 0x3c, - 0x48, 0x99, - }; - const secret_key = try SecretKey.keyGen(input_key_material[0..], null); + const secret_key = try SecretKey.keyGen(input_key_material_a[0..], null); var message_64: [64]u8 = undefined; @memset(message_64[32..], 0xcd); @memset(message_64[0..32], 0x42); @@ -100,13 +89,7 @@ test "bls - fastAggregateVerify uses only first 32 bytes of longer buffer" { } test "bls - verify fails on wrong message" { - const input_key_material: [32]u8 = [_]u8{ - 0x93, 0xad, 0x7e, 0x65, 0xde, 0xad, 0x05, 0x2a, 0x08, 0x3a, - 0x91, 0x0c, 0x8b, 0x72, 0x85, 0x91, 0x46, 0x4c, 0xca, 0x56, - 0x60, 0x5b, 0xb0, 0x56, 0xed, 0xfe, 0x2b, 0x60, 0xa6, 0x3c, - 0x48, 0x99, - }; - const secret_key = try SecretKey.keyGen(input_key_material[0..], null); + const secret_key = try SecretKey.keyGen(input_key_material_a[0..], null); var message = [_]u8{1} ** 32; const signature = sign(secret_key, &message); const public_key = secret_key.toPublicKey(); @@ -115,18 +98,6 @@ test "bls - verify fails on wrong message" { } test "bls - verify fails on wrong public key" { - const input_key_material_a: [32]u8 = [_]u8{ - 0x93, 0xad, 0x7e, 0x65, 0xde, 0xad, 0x05, 0x2a, 0x08, 0x3a, - 0x91, 0x0c, 0x8b, 0x72, 0x85, 0x91, 0x46, 0x4c, 0xca, 0x56, - 0x60, 0x5b, 0xb0, 0x56, 0xed, 0xfe, 0x2b, 0x60, 0xa6, 0x3c, - 0x48, 0x99, - }; - const input_key_material_b: [32]u8 = [_]u8{ - 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, - 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, - 0x0f, 0x10, - }; const secret_key_a = try SecretKey.keyGen(input_key_material_a[0..], null); const secret_key_b = try SecretKey.keyGen(input_key_material_b[0..], null); const message = [_]u8{1} ** 32; @@ -136,13 +107,7 @@ test "bls - verify fails on wrong public key" { } test "bls - fastAggregateVerify false on wrong message" { - const input_key_material: [32]u8 = [_]u8{ - 0x93, 0xad, 0x7e, 0x65, 0xde, 0xad, 0x05, 0x2a, 0x08, 0x3a, - 0x91, 0x0c, 0x8b, 0x72, 0x85, 0x91, 0x46, 0x4c, 0xca, 0x56, - 0x60, 0x5b, 0xb0, 0x56, 0xed, 0xfe, 0x2b, 0x60, 0xa6, 0x3c, - 0x48, 0x99, - }; - const secret_key = try SecretKey.keyGen(input_key_material[0..], null); + const secret_key = try SecretKey.keyGen(input_key_material_a[0..], null); var message = [_]u8{1} ** 32; const signature = sign(secret_key, &message); const public_key = secret_key.toPublicKey();