Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement min_sig #8

Merged
merged 2 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Zig wrapper for [supranational/blst](https://github.com/supranational/blst) nati
- `zig build test`

## Usage
The below shows how to use min_pk namespace
The below shows how to use min_pk namespace, should be the same for min_sig.

```zig
pub const min_pk = @import("blst").min_pk;
Expand Down
16 changes: 8 additions & 8 deletions src/pairing.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const c = @cImport({
@cInclude("blst.h");
});

const PairingError = error{ BufferTooSmall, DstTooSmall };
pub const PairingError = error{ BufferTooSmall, DstTooSmall };

const PTag = enum {
p1,
Expand Down Expand Up @@ -50,7 +50,7 @@ pub const Pairing = struct {
return c.blst_pairing_sizeof();
}

pub fn init(self: *Pairing, hash_or_encode: bool, dst: []const u8) void {
fn init(self: *Pairing, hash_or_encode: bool, dst: []const u8) void {
c.blst_pairing_init(self.ctx(), hash_or_encode, &dst[0], dst.len);
}

Expand All @@ -64,7 +64,7 @@ pub const Pairing = struct {
return ptr;
}

pub fn aggregateG1(self: *Pairing, pk: *const c.blst_p1_affine, pk_validate: bool, sig: ?*const c.blst_p2_affine, sig_groupcheck: bool, msg: []const u8, aug: ?[]u8) BLST_ERROR!void {
pub fn aggregateG1(self: *Pairing, pk: *const c.blst_p1_affine, pk_validate: bool, sig: ?*const c.blst_p2_affine, sig_groupcheck: bool, msg: []const u8, aug: ?[]const u8) BLST_ERROR!void {
const aug_ptr = if (aug != null and aug.?.len > 0) &aug.?[0] else null;
const aug_len = if (aug != null) aug.?.len else 0;
const sig_ptr = if (sig != null) sig.? else null;
Expand All @@ -77,9 +77,9 @@ pub const Pairing = struct {
}
}

pub fn aggregateG2(self: *Pairing, pk: *const c.blst_p2_affine, pk_validate: bool, sig: ?*const c.blst_p1_affine, sig_groupcheck: bool, msg: []u8, aug: ?[]u8) BLST_ERROR!void {
pub fn aggregateG2(self: *Pairing, pk: *const c.blst_p2_affine, pk_validate: bool, sig: ?*const c.blst_p1_affine, sig_groupcheck: bool, msg: []const u8, aug: ?[]const u8) BLST_ERROR!void {
const aug_ptr = if (aug != null and aug.?.len > 0) &aug.?[0] else null;
const aug_len = if (aug != null) aug.?.len else null;
const aug_len = if (aug != null) aug.?.len else 0;
const sig_ptr = if (sig != null) sig.? else null;

const res = c.blst_pairing_chk_n_aggr_pk_in_g2(self.ctx(), pk, pk_validate, sig_ptr, sig_groupcheck, &msg[0], msg.len, aug_ptr, aug_len);
Expand All @@ -92,7 +92,7 @@ pub const Pairing = struct {

// TODO: msgs and scalar should have len > 0
// check for other apis as well
pub fn mulAndAggregateG1(self: *Pairing, pk: *const c.blst_p1_affine, pk_validate: bool, sig: *const c.blst_p2_affine, sig_groupcheck: bool, scalar: []const u8, nbits: usize, msg: []const u8, aug: ?[]u8) BLST_ERROR!void {
pub fn mulAndAggregateG1(self: *Pairing, pk: *const c.blst_p1_affine, pk_validate: bool, sig: *const c.blst_p2_affine, sig_groupcheck: bool, scalar: []const u8, nbits: usize, msg: []const u8, aug: ?[]const u8) BLST_ERROR!void {
const aug_ptr = if (aug != null and aug.?.len > 0) &aug.?[0] else null;
const aug_len = if (aug != null) aug.?.len else 0;

Expand All @@ -104,11 +104,11 @@ pub const Pairing = struct {
}
}

pub fn mulAndAggregateG2(self: *Pairing, pk: *const c.blst_p2_affine, pk_validate: bool, sig: *const c.blst_p1_affine, sig_groupcheck: bool, scalar: []u8, nbits: usize, msg: []u8, aug: ?[]u8) BLST_ERROR!void {
pub fn mulAndAggregateG2(self: *Pairing, pk: *const c.blst_p2_affine, pk_validate: bool, sig: *const c.blst_p1_affine, sig_groupcheck: bool, scalar: []const u8, nbits: usize, msg: []const u8, aug: ?[]const u8) BLST_ERROR!void {
const aug_ptr = if (aug != null and aug.?.len > 0) &aug.?[0] else null;
const aug_len = if (aug != null) aug.?.len else 0;

const res = c.blst_pairing_chk_n_mul_n_aggr_pk_in_g2(self.ctx, pk, pk_validate, sig, sig_groupcheck, &scalar[0], nbits, &msg[0], msg.len, aug_ptr, aug_len);
const res = c.blst_pairing_chk_n_mul_n_aggr_pk_in_g2(self.ctx(), pk, pk_validate, sig, sig_groupcheck, &scalar[0], nbits, &msg[0], msg.len, aug_ptr, aug_len);

const err = toBlstError(res);
if (err != null) {
Expand Down
1 change: 1 addition & 0 deletions src/root.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const std = @import("std");
const testing = std.testing;
pub const min_pk = @import("./sig_variant_min_pk.zig").min_pk;
pub const min_sig = @import("./sig_variant_min_sig.zig").min_sig;

test {
testing.refAllDecls(@This());
Expand Down
72 changes: 55 additions & 17 deletions src/sig_variant.zig
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const std = @import("std");
const testing = std.testing;
const Xoshiro256 = std.rand.Xoshiro256;
const Pairing = @import("./pairing.zig").Pairing;
const P = @import("./pairing.zig").Pairing;
const PairingError = @import("./pairing.zig").PairingError;

const c = @cImport({
@cInclude("blst.h");
Expand Down Expand Up @@ -56,6 +57,48 @@ pub fn createSigVariant(
sig_aggr_in_group_fn: anytype,
) type {
// TODO: implement MultiPoint
const Pairing = struct {
p: P,
pub fn new(buffer: []u8, hoe: bool, dst: []const u8) PairingError!@This() {
const p = try P.new(buffer, hoe, dst);
return .{ .p = p };
}

pub fn sizeOf() usize {
return P.sizeOf();
}

pub fn aggregate(self: *@This(), pk: *const pk_aff_type, pk_validate: bool, sig: ?*const sig_aff_type, sig_groupcheck: bool, msg: []const u8, aug: ?[]u8) BLST_ERROR!void {
if (pk_comp_size == 48) {
// min_pk
return self.p.aggregateG1(pk, pk_validate, sig, sig_groupcheck, msg, aug);
} else {
// min_sig
return self.p.aggregateG2(pk, pk_validate, sig, sig_groupcheck, msg, aug);
}
}

pub fn mulAndAggregate(self: *@This(), pk: *const pk_aff_type, pk_validate: bool, sig: *const sig_aff_type, sig_groupcheck: bool, scalar: []const u8, nbits: usize, msg: []const u8, aug: ?[]u8) BLST_ERROR!void {
if (pk_comp_size == 48) {
// min_pk
return self.p.mulAndAggregateG1(pk, pk_validate, sig, sig_groupcheck, scalar, nbits, msg, aug);
} else {
// min_sig
return self.p.mulAndAggregateG2(pk, pk_validate, sig, sig_groupcheck, scalar, nbits, msg, aug);
}
}

pub fn commit(self: *@This()) void {
self.p.commit();
}

pub fn finalVerify(self: *@This(), ggtsig: ?*const c.blst_fp12) bool {
return self.p.finalVerify(ggtsig);
}

// add more methods here if needed
};

// TODO: implement Clone, Copy, Equal
const PublicKey = struct {
point: pk_aff_type,
Expand Down Expand Up @@ -93,7 +136,7 @@ pub fn createSigVariant(
// Serdes

pub fn compress(self: *const @This()) [pk_comp_size]u8 {
var pk_comp = [_]u8{0} ** 48;
var pk_comp = [_]u8{0} ** pk_comp_size;
pk_comp_fn(&pk_comp[0], &self.point);
return pk_comp;
}
Expand All @@ -105,7 +148,7 @@ pub fn createSigVariant(
}

pub fn uncompress(pk_comp: []const u8) BLST_ERROR!@This() {
if (pk_comp.len == 48 and (pk_comp[0] & 0x80) != 0) {
if (pk_comp.len == pk_comp_size and (pk_comp[0] & 0x80) != 0) {
var pk = @This().default();
const res = pk_uncomp_fn(&pk.point, &pk_comp[0]);
const err = toBlstError(res);
Expand All @@ -119,8 +162,8 @@ pub fn createSigVariant(
}

pub fn deserialize(pk_in: []const u8) BLST_ERROR!@This() {
if ((pk_in.len == 96 and (pk_in[0] & 0x80) == 0) or
(pk_in.len == 48 and (pk_in[0] & 0x80) != 0))
if ((pk_in.len == pk_ser_size and (pk_in[0] & 0x80) == 0) or
(pk_in.len == pk_comp_size and (pk_in[0] & 0x80) != 0))
{
var pk = @This().default();
const res = pk_deser_fn(&pk.point, &pk_in[0]);
Expand Down Expand Up @@ -212,13 +255,11 @@ pub fn createSigVariant(
try pk.validate();
}

// c.blst_p1_add_or_double_affine(&self.point, &self.point, &pk.point);
pk_add_or_dbl_aff_fn(&self.point, &self.point, &pk.point);
}
};

const Signature = struct {
// point: c.blst_p2_affine,
point: sig_aff_type,

pub fn default() @This() {
Expand Down Expand Up @@ -280,10 +321,10 @@ pub fn createSigVariant(
else => return BLST_ERROR.FAILED_PAIRING,
};

try pairing.aggregateG1(&pks[0].point, pks_validate, &self.point, sig_groupcheck, msgs[0], null);
try pairing.aggregate(&pks[0].point, pks_validate, &self.point, sig_groupcheck, msgs[0], null);

for (1..n_elems) |i| {
try pairing.aggregateG1(&pks[i].point, pks_validate, null, false, msgs[i], null);
try pairing.aggregate(&pks[i].point, pks_validate, null, false, msgs[i], null);
}

pairing.commit();
Expand Down Expand Up @@ -330,7 +371,7 @@ pub fn createSigVariant(
};

for (0..n_elems) |i| {
try pairing.mulAndAggregateG1(&pks[i].point, pks_validate, &sigs[i].point, sigs_groupcheck, rands[i], rand_bits, msgs[i], null);
try pairing.mulAndAggregate(&pks[i].point, pks_validate, &sigs[i].point, sigs_groupcheck, rands[i], rand_bits, msgs[i], null);
}

pairing.commit();
Expand All @@ -353,15 +394,13 @@ pub fn createSigVariant(
}

pub fn serialize(self: *const @This()) [sig_ser_size]u8 {
// var sig_out = [_]u8{0} ** 192;
var sig_out = [_]u8{0} ** sig_ser_size;
// c.blst_p2_affine_serialize(&sig_out[0], &self.point);
sig_ser_fn(&sig_out[0], &self.point);
return sig_out;
}

pub fn uncompress(sig_comp: []const u8) BLST_ERROR!@This() {
if (sig_comp.len == 96 and (sig_comp[0] & 0x80) != 0) {
if (sig_comp.len == sig_comp_size and (sig_comp[0] & 0x80) != 0) {
var sig = @This().default();
const res = sig_uncomp_fn(&sig.point, &sig_comp[0]);
if (res != null) {
Expand All @@ -374,7 +413,7 @@ pub fn createSigVariant(
}

pub fn deserialize(sig_in: []const u8) BLST_ERROR!@This() {
if ((sig_in.len == 192 and (sig_in[0] & 0x80) == 0) or (sig_in.len == 96 and sig_in[0] & 0x80) != 0) {
if ((sig_in.len == sig_ser_size and (sig_in[0] & 0x80) == 0) or (sig_in.len == sig_comp_size and sig_in[0] & 0x80) != 0) {
var sig = @This().default();
const res = sig_deser_fn(&sig.point, &sig_in[0]);
const err = toBlstError(res);
Expand All @@ -391,7 +430,7 @@ pub fn createSigVariant(
return @This().deserialize(sig_in);
}

pub fn toBytes(self: *const @This()) [96]u8 {
pub fn toBytes(self: *const @This()) [sig_comp_size]u8 {
return self.compress();
}

Expand Down Expand Up @@ -574,7 +613,7 @@ pub fn createSigVariant(
// Sign
pub fn sign(self: *const @This(), msg: []const u8, dst: []const u8, aug: ?[]const u8) Signature {
// TODO - would the user like the serialized/compressed sig as well?
var q = util.default_blst_p2();
var q = default_agg_sig_fn();
var sig_aff = Signature.default();
const aug_ptr = if (aug != null and aug.?.len > 0) &aug.?[0] else null;
const aug_len = if (aug != null) aug.?.len else 0;
Expand Down Expand Up @@ -643,7 +682,6 @@ pub fn createSigVariant(

pub fn pubkeyFromAggregate(agg_pk: *const AggregatePublicKey) PublicKey {
var pk_aff = PublicKey.default();
// c.blst_p1_to_affine(&pk_aff.point, &agg_pk.point);
pk_to_aff_fn(&pk_aff.point, &agg_pk.point);
return pk_aff;
}
Expand Down
77 changes: 77 additions & 0 deletions src/sig_variant_min_sig.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
const std = @import("std");
const testing = std.testing;
const Xoshiro256 = std.rand.Xoshiro256;
const Pairing = @import("./pairing.zig").Pairing;
const c = @cImport({
@cInclude("blst.h");
});
const util = @import("util.zig");
const BLST_ERROR = util.BLST_ERROR;
const toBlstError = util.toBlstError;

const createSigVariant = @import("./sig_variant.zig").createSigVariant;

const SigVariant = createSigVariant(
util.default_blst_p2_affline,
util.default_blst_p2,
util.default_blst_p1_affine,
util.default_blst_p1,
c.blst_p2,
c.blst_p2_affine,
c.blst_p1,
c.blst_p1_affine,
c.blst_sk_to_pk2_in_g2,
true,
c.blst_hash_to_g1,
c.blst_sign_pk2_in_g2,
// c.blst_p2_affine_is_equal,
// c.blst_p1_affine_is_equal,
c.blst_core_verify_pk_in_g2,
c.blst_p2_affine_in_g2,
c.blst_p2_to_affine,
c.blst_p2_from_affine,
c.blst_p2_affine_serialize,
c.blst_p2_affine_compress,
c.blst_p2_deserialize,
c.blst_p2_uncompress,
96,
192,
c.blst_p1_affine_in_g1,
c.blst_p1_to_affine,
c.blst_p1_from_affine,
c.blst_p1_affine_serialize,
c.blst_p1_affine_compress,
c.blst_p1_deserialize,
c.blst_p1_uncompress,
48,
96,
c.blst_p2_add_or_double,
c.blst_p2_add_or_double_affine,
c.blst_p1_add_or_double,
c.blst_p1_add_or_double_affine,
c.blst_p2_affine_is_inf,
c.blst_p1_affine_is_inf,
c.blst_p1_in_g1,
);

pub const min_sig = struct {
pub const PublicKey = SigVariant.createPublicKey();
pub const AggregatePublicKey = SigVariant.createAggregatePublicKey();
pub const Signature = SigVariant.createSignature();
pub const AggregateSignature = SigVariant.createAggregateSignature();
pub const SecretKey = SigVariant.createSecretKey();
};

test "test_sign_n_verify" {
try SigVariant.testSignNVerify();
}

test "test_aggregate" {
try SigVariant.testAggregate();
}

test "test_multiple_agg_sigs" {
try SigVariant.testMultipleAggSigs();
}

// TODO test_serialization, test_serde, test_multi_point
14 changes: 14 additions & 0 deletions src/util.zig
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,20 @@ pub fn default_blst_p1_affline() c.blst_p1_affine {
};
}

pub fn default_blst_p1_affine() c.blst_p1_affine {
return .{
.x = default_blst_fp(),
.y = default_blst_fp(),
};
}

pub fn default_blst_p2_affline() c.blst_p2_affine {
return .{
.x = default_blst_fp2(),
.y = default_blst_fp2(),
};
}

pub fn default_blst_p1() c.blst_p1 {
return .{
.x = default_blst_fp(),
Expand Down
Loading