Skip to content

Commit 877819f

Browse files
committed
fixup! Add initial zig bindings.
1 parent f2ca8ab commit 877819f

File tree

4 files changed

+84
-23
lines changed

4 files changed

+84
-23
lines changed

bindings/zig/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# blst for [Zig](https://ziglang.org/)
22

3-
The object-oriented interface is modeled after [C++ interface](../blst.hpp), but for the moment of this writing is a subset of it, sufficient to produce and verify individual and aggregated signatures.
3+
The object-oriented interface is modeled after [C++ interface](../blst.hpp), but for the moment of this writing is a subset of it, sufficient to produce and verify individual and aggregated signatures. See [tests.zig](tests.zig) for usage examples.
44

55
## Adding dependency to your project
66

bindings/zig/blst.zig

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ pub const Pairing = struct {
131131

132132
pub fn raw_aggregate(self: *Pairing, q: *const P2_Affine,
133133
p: *const P1_Affine) void {
134-
c.blst_pairing_raw_aggregate(@ptrCast(self.ctx), q, p);
134+
c.blst_pairing_raw_aggregate(@ptrCast(self.ctx), &q.point, &p.point);
135135
}
136136

137137
pub fn as_fp12(self: *Pairing) *const PT {
@@ -230,7 +230,7 @@ pub const P1_Affine = struct {
230230
}
231231

232232
pub fn in_group(self: *const P1_Affine) bool {
233-
return c.blst_p1_affine_in_group(&self.point);
233+
return c.blst_p1_affine_in_g1(&self.point);
234234
}
235235

236236
pub fn is_inf(self: *const P1_Affine) bool {
@@ -334,7 +334,7 @@ pub const P1 = struct {
334334
}
335335

336336
pub fn in_group(self: *const P1) bool {
337-
return c.blst_p1_in_group(&self.point);
337+
return c.blst_p1_in_g1(&self.point);
338338
}
339339

340340
pub fn is_inf(self: *const P1) bool {
@@ -346,7 +346,7 @@ pub const P1 = struct {
346346
}
347347

348348
pub fn aggregate(self: *P1, p: *const P1_Affine) !void {
349-
if (!c.blst_p1_affine_in_g1(p)) {
349+
if (!c.blst_p1_affine_in_g1(&p.point)) {
350350
return Error.POINT_NOT_IN_GROUP;
351351
}
352352
c.blst_p1_add_or_double_affine(&self.point, &self.point, &p.point);
@@ -449,7 +449,7 @@ pub const P2_Affine = struct {
449449
}
450450

451451
pub fn in_group(self: *const P2_Affine) bool {
452-
return c.blst_p2_affine_in_group(&self.point);
452+
return c.blst_p2_affine_in_g2(&self.point);
453453
}
454454

455455
pub fn is_inf(self: *const P2_Affine) bool {
@@ -553,7 +553,7 @@ pub const P2 = struct {
553553
}
554554

555555
pub fn in_group(self: *const P2) bool {
556-
return c.blst_p2_in_group(&self.point);
556+
return c.blst_p2_in_g2(&self.point);
557557
}
558558

559559
pub fn is_inf(self: *const P2) bool {
@@ -565,7 +565,7 @@ pub const P2 = struct {
565565
}
566566

567567
pub fn aggregate(self: *P2, p: *const P2_Affine) !void {
568-
if (!c.blst_p2_affine_in_g2(p)) {
568+
if (!c.blst_p2_affine_in_g2(&p.point)) {
569569
return Error.POINT_NOT_IN_GROUP;
570570
}
571571
c.blst_p2_add_or_double_affine(&self.point, &self.point, &p.point);

bindings/zig/generate.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@
131131
132132
pub fn raw_aggregate(self: *Pairing, q: *const P2_Affine,
133133
p: *const P1_Affine) void {
134-
c.blst_pairing_raw_aggregate(@ptrCast(self.ctx), q, p);
134+
c.blst_pairing_raw_aggregate(@ptrCast(self.ctx), &q.point, &p.point);
135135
}
136136
137137
pub fn as_fp12(self: *Pairing) *const PT {
@@ -230,7 +230,7 @@
230230
}
231231
232232
pub fn in_group(self: *const P1_Affine) bool {
233-
return c.blst_p1_affine_in_group(&self.point);
233+
return c.blst_p1_affine_in_g1(&self.point);
234234
}
235235
236236
pub fn is_inf(self: *const P1_Affine) bool {
@@ -334,7 +334,7 @@
334334
}
335335
336336
pub fn in_group(self: *const P1) bool {
337-
return c.blst_p1_in_group(&self.point);
337+
return c.blst_p1_in_g1(&self.point);
338338
}
339339
340340
pub fn is_inf(self: *const P1) bool {
@@ -346,7 +346,7 @@
346346
}
347347
348348
pub fn aggregate(self: *P1, p: *const P1_Affine) !void {
349-
if (!c.blst_p1_affine_in_g1(p)) {
349+
if (!c.blst_p1_affine_in_g1(&p.point)) {
350350
return Error.POINT_NOT_IN_GROUP;
351351
}
352352
c.blst_p1_add_or_double_affine(&self.point, &self.point, &p.point);

bindings/zig/tests.zig

Lines changed: 72 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,6 @@ test "sign/verify" {
2424
const ret = sig.core_verify(&pk, true, msg, DST, &pk_for_wire);
2525

2626
try std.testing.expectEqual(ret, .SUCCESS);
27-
28-
// ... the same thing through Pairing interface.
29-
30-
var ctx = try blst.Pairing.init(true, DST, std.testing.allocator);
31-
defer ctx.deinit();
32-
33-
try std.testing.expectEqual(ctx.aggregate(&pk, &sig, msg, &pk_for_wire), .SUCCESS);
34-
ctx.commit();
35-
try std.testing.expectEqual(ctx.finalverify(null), true);
36-
37-
std.debug.print("OK\n", .{});
3827
}
3928

4029
test "uniq" {
@@ -49,3 +38,75 @@ test "uniq" {
4938
try std.testing.expectEqual(ctx.is_uniq(msg), next < msgs.len);
5039
}
5140
}
41+
42+
fn box(allocator: std.mem.Allocator, src: []const u8) ![]u8 {
43+
const ret = try allocator.alloc(u8, src.len);
44+
@memcpy(ret, src);
45+
return ret;
46+
}
47+
48+
test "aggregateverify" {
49+
const allocator = std.testing.allocator;
50+
const N = 3;
51+
var msgs: [N][]const u8 = undefined;
52+
53+
for (0..N) |i| {
54+
msgs[i] = try std.fmt.allocPrint(allocator, "assertion{}", .{i});
55+
}
56+
57+
const password = [_]u8{'*'} ** 32;
58+
var SK = blst.SecretKey{};
59+
defer SK.deinit();
60+
61+
// emulate N "senders"...
62+
63+
const DST = "MY-DST";
64+
var pks: [N][]const u8 = undefined;
65+
var sigs: [N][]const u8 = undefined;
66+
67+
for (0..N) |i| {
68+
SK.keygen(&password, msgs[i]);
69+
pks[i] = try box(allocator, &(try blst.P1.from(&SK)).serialize());
70+
sigs[i] = try box(allocator, &blst.P2.hash_to(msgs[i], DST, null).sign_with(&SK).serialize());
71+
}
72+
73+
// ... basic scheme on the "receiver" side.
74+
75+
var uniq = try blst.Uniq.init(msgs.len, std.testing.allocator);
76+
defer uniq.deinit();
77+
78+
var aggregated = try blst.P2.from(sigs[0]);
79+
try std.testing.expectEqual(aggregated.in_group(), true);
80+
for (1..N) |i| {
81+
try aggregated.aggregate(&try blst.P2_Affine.from(sigs[i]));
82+
}
83+
84+
var ctx = try blst.Pairing.init(true, DST, std.testing.allocator);
85+
defer ctx.deinit();
86+
87+
// The basic scheme requires messages to be checked for uniqueness.
88+
try std.testing.expectEqual(uniq.is_uniq(msgs[0]), true);
89+
// The below .aggregate() method doesn't vet public keys with
90+
// rationale that application would cache the results of the
91+
// group checks. Hence they need to be vetted separately.
92+
var pk = try blst.P1_Affine.from(pks[0]);
93+
try std.testing.expectEqual(pk.in_group(), true);
94+
try std.testing.expectEqual(ctx.aggregate(&pk, &aggregated.to_affine(), msgs[0], null),
95+
.SUCCESS);
96+
for (1..N) |i| {
97+
try std.testing.expectEqual(uniq.is_uniq(msgs[i]), true);
98+
pk = try blst.P1_Affine.from(pks[i]);
99+
try std.testing.expectEqual(pk.in_group(), true);
100+
try std.testing.expectEqual(ctx.aggregate(&pk, null, msgs[i], null),
101+
.SUCCESS);
102+
}
103+
104+
ctx.commit();
105+
try std.testing.expectEqual(ctx.finalverify(null), true);
106+
107+
for (0..N) |i| {
108+
allocator.free(pks[i]);
109+
allocator.free(sigs[i]);
110+
allocator.free(msgs[i]);
111+
}
112+
}

0 commit comments

Comments
 (0)