Skip to content

Commit 35e590c

Browse files
committed
fixup! Add initial zig bindings.
1 parent 36a1abc commit 35e590c

File tree

3 files changed

+154
-55
lines changed

3 files changed

+154
-55
lines changed

bindings/zig/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# blst for [Zig](https://ziglang.org/)
2+
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 signatures.
4+
5+
## Adding dependency to your project
6+
7+
Execute
8+
```
9+
zig fetch --save git+https://github.com/dot-asm/blst#zig-bindings
10+
```
11+
and add an equivalent of the following line to your build.zig prior to `b.installArtifact(exe)`:
12+
```
13+
exe.root_module.addImport("blst", b.dependency("blst", .{}).module("blst"));
14+
```
15+
You should now be able to `@import("blst")` in your application code. The abovementioned fetch command can be used to update the reference.

bindings/zig/blst.zig

Lines changed: 90 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ pub const ERROR = enum(c.BLST_ERROR) {
3030

3131
pub fn as_error(self: ERROR) Error {
3232
return switch (self) {
33-
ERROR.BAD_ENCODING => Error.BAD_ENCODING,
34-
ERROR.POINT_NOT_ON_CURVE => Error.POINT_NOT_ON_CURVE,
35-
ERROR.POINT_NOT_IN_GROUP => Error.POINT_NOT_IN_GROUP,
36-
ERROR.AGGR_TYPE_MISMATCH => Error.AGGR_TYPE_MISMATCH,
37-
ERROR.VERIFY_FAIL => Error.VERIFY_FAIL,
38-
ERROR.PK_IS_INFINITY => Error.PK_IS_INFINITY,
39-
ERROR.BAD_SCALAR => Error.BAD_SCALAR,
40-
else => Error.Unknown,
33+
.BAD_ENCODING => Error.BAD_ENCODING,
34+
.POINT_NOT_ON_CURVE => Error.POINT_NOT_ON_CURVE,
35+
.POINT_NOT_IN_GROUP => Error.POINT_NOT_IN_GROUP,
36+
.AGGR_TYPE_MISMATCH => Error.AGGR_TYPE_MISMATCH,
37+
.VERIFY_FAIL => Error.VERIFY_FAIL,
38+
.PK_IS_INFINITY => Error.PK_IS_INFINITY,
39+
.BAD_SCALAR => Error.BAD_SCALAR,
40+
else => Error.Unknown,
4141
};
4242
}
4343
};
@@ -66,10 +66,23 @@ pub const P2_SERIALIZE_BYTES = FP_BYTES*4;
6666
pub const P1_Affine = struct {
6767
point : c.blst_p1_affine = c.blst_p1_affine{},
6868

69-
pub fn from(in: []const u8) !P1_Affine {
70-
var ret : P1_Affine = undefined;
71-
const err = ret.deserialize(in);
72-
return if (err == ERROR.SUCCESS) ret else err.as_error();
69+
pub fn from(in: anytype) !P1_Affine {
70+
switch (@TypeOf(in)) {
71+
*const P1,
72+
*P1 => return in.to_affine(),
73+
P1 => @compileError("expected type '*const blst.P1', found 'blst.P1'"),
74+
else => |T| {
75+
switch(@typeInfo(T)) {
76+
.pointer => { const s: []const u8 = in; _ = s; },
77+
else => @compileError("expected type '[]const u8', found '" ++ @typeName(T) ++ "'"),
78+
}
79+
80+
var ret : P1_Affine = undefined;
81+
const err = ret.deserialize(in);
82+
return if (err == ERROR.SUCCESS) ret else err.as_error();
83+
},
84+
}
85+
unreachable;
7386
}
7487

7588
pub fn deserialize(self: *P1_Affine, in: []const u8) ERROR {
@@ -147,10 +160,26 @@ pub const P1_Affine = struct {
147160
pub const P1 = struct {
148161
point : c.blst_p1 = c.blst_p1{},
149162

150-
pub fn from(in: []const u8) !P1 {
151-
var ret : P1 = undefined;
152-
const err = ret.deserialize(in);
153-
return if (err == ERROR.SUCCESS) ret else err.as_error();
163+
pub fn from(in: anytype) !P1 {
164+
switch (@TypeOf(in)) {
165+
*const SecretKey,
166+
*SecretKey => return P1.public_key(in),
167+
SecretKey => @compileError("expected type '*const blst.SecretKey', found 'blst.SecretKey'"),
168+
*const P1_Affine,
169+
*P1_Affine => return in.to_jacobian(),
170+
P1_Affine => @compileError("expected type '*const blst.P1_Affine', found 'blst.P1_Affine'"),
171+
else => |T| {
172+
switch(@typeInfo(T)) {
173+
.pointer => { const s: []const u8 = in; _ = s; },
174+
else => @compileError("expected type '[]const u8', found '" ++ @typeName(T) ++ "'"),
175+
}
176+
177+
var ret : P1 = undefined;
178+
const err = ret.deserialize(in);
179+
return if (err == ERROR.SUCCESS) ret else err.as_error();
180+
},
181+
}
182+
unreachable;
154183
}
155184

156185
pub fn deserialize(self: *P1, in: []const u8) ERROR {
@@ -213,7 +242,7 @@ pub const P1 = struct {
213242
if (!c.blst_p1_affine_in_g1(p)) {
214243
return Error.POINT_NOT_IN_GROUP;
215244
}
216-
c.blst_p1_add_or_double(&self.point, &self.point, &p.point);
245+
c.blst_p1_add_or_double_affine(&self.point, &self.point, &p.point);
217246
}
218247

219248
pub fn hash_to(msg: []const u8, DST: []const u8, aug: ?[]const u8) P1 {
@@ -236,10 +265,9 @@ pub const P1 = struct {
236265
return ret;
237266
}
238267

239-
pub fn sign_with(self: *const P1, sk: *const SecretKey) P1 {
240-
var ret : P1 = undefined;
241-
c.blst_sign_pk_in_g2(&ret.point, &self.point, &sk.key);
242-
return ret;
268+
pub fn sign_with(self: *const P1, sk: *const SecretKey) *P1 {
269+
c.blst_sign_pk_in_g2(@constCast(&self.point), &self.point, &sk.key);
270+
return @constCast(self);
243271
}
244272

245273
pub fn to_affine(self: *const P1) P1_Affine {
@@ -259,10 +287,23 @@ pub const P1 = struct {
259287
pub const P2_Affine = struct {
260288
point : c.blst_p2_affine = c.blst_p2_affine{},
261289

262-
pub fn from(in: []const u8) !P2_Affine {
263-
var ret : P2_Affine = undefined;
264-
const err = ret.deserialize(in);
265-
return if (err == ERROR.SUCCESS) ret else err.as_error();
290+
pub fn from(in: anytype) !P2_Affine {
291+
switch (@TypeOf(in)) {
292+
*const P2,
293+
*P2 => return in.to_affine(),
294+
P2 => @compileError("expected type '*const blst.P2', found 'blst.P2'"),
295+
else => |T| {
296+
switch(@typeInfo(T)) {
297+
.pointer => { const s: []const u8 = in; _ = s; },
298+
else => @compileError("expected type '[]const u8', found '" ++ @typeName(T) ++ "'"),
299+
}
300+
301+
var ret : P2_Affine = undefined;
302+
const err = ret.deserialize(in);
303+
return if (err == ERROR.SUCCESS) ret else err.as_error();
304+
},
305+
}
306+
unreachable;
266307
}
267308

268309
pub fn deserialize(self: *P2_Affine, in: []const u8) ERROR {
@@ -340,10 +381,26 @@ pub const P2_Affine = struct {
340381
pub const P2 = struct {
341382
point : c.blst_p2 = c.blst_p2{},
342383

343-
pub fn from(in: []const u8) !P2 {
344-
var ret : P2 = undefined;
345-
const err = ret.deserialize(in);
346-
return if (err == ERROR.SUCCESS) ret else err.as_error();
384+
pub fn from(in: anytype) !P2 {
385+
switch (@TypeOf(in)) {
386+
*const SecretKey,
387+
*SecretKey => return P2.public_key(in),
388+
SecretKey => @compileError("expected type '*const blst.SecretKey', found 'blst.SecretKey'"),
389+
*const P2_Affine,
390+
*P2_Affine => return in.to_jacobian(),
391+
P2_Affine => @compileError("expected type '*const blst.P2_Affine', found 'blst.P2_Affine'"),
392+
else => |T| {
393+
switch(@typeInfo(T)) {
394+
.pointer => { const s: []const u8 = in; _ = s; },
395+
else => @compileError("expected type '[]const u8', found '" ++ @typeName(T) ++ "'"),
396+
}
397+
398+
var ret : P2 = undefined;
399+
const err = ret.deserialize(in);
400+
return if (err == ERROR.SUCCESS) ret else err.as_error();
401+
},
402+
}
403+
unreachable;
347404
}
348405

349406
pub fn deserialize(self: *P2, in: []const u8) ERROR {
@@ -406,7 +463,7 @@ pub const P2 = struct {
406463
if (!c.blst_p2_affine_in_g2(p)) {
407464
return Error.POINT_NOT_IN_GROUP;
408465
}
409-
c.blst_p2_add_or_double(&self.point, &self.point, &p.point);
466+
c.blst_p2_add_or_double_affine(&self.point, &self.point, &p.point);
410467
}
411468

412469
pub fn hash_to(msg: []const u8, DST: []const u8, aug: ?[]const u8) P2 {
@@ -429,10 +486,9 @@ pub const P2 = struct {
429486
return ret;
430487
}
431488

432-
pub fn sign_with(self: *const P2, sk: *const SecretKey) P2 {
433-
var ret : P2 = undefined;
434-
c.blst_sign_pk_in_g1(&ret.point, &self.point, &sk.key);
435-
return ret;
489+
pub fn sign_with(self: *const P2, sk: *const SecretKey) *P2 {
490+
c.blst_sign_pk_in_g1(@constCast(&self.point), &self.point, &sk.key);
491+
return @constCast(self);
436492
}
437493

438494
pub fn to_affine(self: *const P2) P2_Affine {

bindings/zig/generate.py

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,14 @@ def newer(*files):
6262
6363
pub fn as_error(self: ERROR) Error {
6464
return switch (self) {
65-
ERROR.BAD_ENCODING => Error.BAD_ENCODING,
66-
ERROR.POINT_NOT_ON_CURVE => Error.POINT_NOT_ON_CURVE,
67-
ERROR.POINT_NOT_IN_GROUP => Error.POINT_NOT_IN_GROUP,
68-
ERROR.AGGR_TYPE_MISMATCH => Error.AGGR_TYPE_MISMATCH,
69-
ERROR.VERIFY_FAIL => Error.VERIFY_FAIL,
70-
ERROR.PK_IS_INFINITY => Error.PK_IS_INFINITY,
71-
ERROR.BAD_SCALAR => Error.BAD_SCALAR,
72-
else => Error.Unknown,
65+
.BAD_ENCODING => Error.BAD_ENCODING,
66+
.POINT_NOT_ON_CURVE => Error.POINT_NOT_ON_CURVE,
67+
.POINT_NOT_IN_GROUP => Error.POINT_NOT_IN_GROUP,
68+
.AGGR_TYPE_MISMATCH => Error.AGGR_TYPE_MISMATCH,
69+
.VERIFY_FAIL => Error.VERIFY_FAIL,
70+
.PK_IS_INFINITY => Error.PK_IS_INFINITY,
71+
.BAD_SCALAR => Error.BAD_SCALAR,
72+
else => Error.Unknown,
7373
};
7474
}
7575
};
@@ -98,10 +98,23 @@ def newer(*files):
9898
pub const P1_Affine = struct {
9999
point : c.blst_p1_affine = c.blst_p1_affine{},
100100
101-
pub fn from(in: []const u8) !P1_Affine {
102-
var ret : P1_Affine = undefined;
103-
const err = ret.deserialize(in);
104-
return if (err == ERROR.SUCCESS) ret else err.as_error();
101+
pub fn from(in: anytype) !P1_Affine {
102+
switch (@TypeOf(in)) {
103+
*const P1,
104+
*P1 => return in.to_affine(),
105+
P1 => @compileError("expected type '*const blst.P1', found 'blst.P1'"),
106+
else => |T| {
107+
switch(@typeInfo(T)) {
108+
.pointer => { const s: []const u8 = in; _ = s; },
109+
else => @compileError("expected type '[]const u8', found '" ++ @typeName(T) ++ "'"),
110+
}
111+
112+
var ret : P1_Affine = undefined;
113+
const err = ret.deserialize(in);
114+
return if (err == ERROR.SUCCESS) ret else err.as_error();
115+
},
116+
}
117+
unreachable;
105118
}
106119
107120
pub fn deserialize(self: *P1_Affine, in: []const u8) ERROR {
@@ -179,10 +192,26 @@ def newer(*files):
179192
pub const P1 = struct {
180193
point : c.blst_p1 = c.blst_p1{},
181194
182-
pub fn from(in: []const u8) !P1 {
183-
var ret : P1 = undefined;
184-
const err = ret.deserialize(in);
185-
return if (err == ERROR.SUCCESS) ret else err.as_error();
195+
pub fn from(in: anytype) !P1 {
196+
switch (@TypeOf(in)) {
197+
*const SecretKey,
198+
*SecretKey => return P1.public_key(in),
199+
SecretKey => @compileError("expected type '*const blst.SecretKey', found 'blst.SecretKey'"),
200+
*const P1_Affine,
201+
*P1_Affine => return in.to_jacobian(),
202+
P1_Affine => @compileError("expected type '*const blst.P1_Affine', found 'blst.P1_Affine'"),
203+
else => |T| {
204+
switch(@typeInfo(T)) {
205+
.pointer => { const s: []const u8 = in; _ = s; },
206+
else => @compileError("expected type '[]const u8', found '" ++ @typeName(T) ++ "'"),
207+
}
208+
209+
var ret : P1 = undefined;
210+
const err = ret.deserialize(in);
211+
return if (err == ERROR.SUCCESS) ret else err.as_error();
212+
},
213+
}
214+
unreachable;
186215
}
187216
188217
pub fn deserialize(self: *P1, in: []const u8) ERROR {
@@ -245,7 +274,7 @@ def newer(*files):
245274
if (!c.blst_p1_affine_in_g1(p)) {
246275
return Error.POINT_NOT_IN_GROUP;
247276
}
248-
c.blst_p1_add_or_double(&self.point, &self.point, &p.point);
277+
c.blst_p1_add_or_double_affine(&self.point, &self.point, &p.point);
249278
}
250279
251280
pub fn hash_to(msg: []const u8, DST: []const u8, aug: ?[]const u8) P1 {
@@ -268,10 +297,9 @@ def newer(*files):
268297
return ret;
269298
}
270299
271-
pub fn sign_with(self: *const P1, sk: *const SecretKey) P1 {
272-
var ret : P1 = undefined;
273-
c.blst_sign_pk_in_g2(&ret.point, &self.point, &sk.key);
274-
return ret;
300+
pub fn sign_with(self: *const P1, sk: *const SecretKey) *P1 {
301+
c.blst_sign_pk_in_g2(@constCast(&self.point), &self.point, &sk.key);
302+
return @constCast(self);
275303
}
276304
277305
pub fn to_affine(self: *const P1) P1_Affine {

0 commit comments

Comments
 (0)