Files

608 lines
19 KiB
Zig

//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// DO NOT EDIT THIS FILE!!!
// The file is auto-generated by generate.py
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Copyright Supranational LLC
// SPDX-License-Identifier: Apache-2.0
const std = @import("std");
pub const c = @import("c.zig");
pub const Error = error{
BAD_ENCODING,
POINT_NOT_ON_CURVE,
POINT_NOT_IN_GROUP,
AGGR_TYPE_MISMATCH,
VERIFY_FAIL,
PK_IS_INFINITY,
BAD_SCALAR,
Unknown,
};
pub const ERROR = enum(c.ERROR) {
SUCCESS = c.SUCCESS,
BAD_ENCODING = c.BAD_ENCODING,
POINT_NOT_ON_CURVE = c.POINT_NOT_ON_CURVE,
POINT_NOT_IN_GROUP = c.POINT_NOT_IN_GROUP,
AGGR_TYPE_MISMATCH = c.AGGR_TYPE_MISMATCH,
VERIFY_FAIL = c.VERIFY_FAIL,
PK_IS_INFINITY = c.PK_IS_INFINITY,
BAD_SCALAR = c.BAD_SCALAR,
pub fn as_error(self: ERROR) Error {
return switch (self) {
.BAD_ENCODING => Error.BAD_ENCODING,
.POINT_NOT_ON_CURVE => Error.POINT_NOT_ON_CURVE,
.POINT_NOT_IN_GROUP => Error.POINT_NOT_IN_GROUP,
.AGGR_TYPE_MISMATCH => Error.AGGR_TYPE_MISMATCH,
.VERIFY_FAIL => Error.VERIFY_FAIL,
.PK_IS_INFINITY => Error.PK_IS_INFINITY,
.BAD_SCALAR => Error.BAD_SCALAR,
else => Error.Unknown,
};
}
};
pub const SecretKey = struct {
key: c.scalar = c.scalar{},
pub fn keygen(self: *SecretKey, IKM: []const u8, info: ?[]const u8) void {
const opt = info orelse &[_]u8{};
c.keygen(&self.key, @ptrCast(IKM), IKM.len,
@ptrCast(opt), opt.len);
}
pub fn deinit(self: *SecretKey) void {
self.key = c.scalar{};
}
};
pub const PT = c.fp12;
pub const Pairing = struct {
ctx: []u64 = &[_]u64{},
allocator: std.mem.Allocator,
pub fn init(hash_or_encode: bool, DST: []const u8,
allocator: std.mem.Allocator) !Pairing {
const nlimbs = (c.pairing_sizeof() + @sizeOf(u64) - 1) / @sizeOf(u64);
const buffer = try allocator.alloc(u64, nlimbs);
c.pairing_init(@ptrCast(buffer), hash_or_encode, &DST[0], DST.len);
return Pairing{
.ctx = buffer,
.allocator = allocator,
};
}
pub fn deinit(self: *Pairing) void {
self.allocator.free(self.ctx);
self.ctx = &[_]u64{};
}
pub fn aggregate(self: *Pairing, pk: anytype, sig: anytype,
msg: []const u8, aug: ?[]const u8) ERROR {
const opt = aug orelse &[_]u8{};
var err: c.ERROR = undefined;
switch (@TypeOf(pk)) {
*const P1_Affine, *P1_Affine => {
const sigp: [*c]const c.p2_affine = switch (@TypeOf(sig)) {
@TypeOf(null) => null,
else => &sig.point,
};
err = c.pairing_aggregate_pk_in_g1(@ptrCast(self.ctx),
&pk.point, sigp,
@ptrCast(msg), msg.len,
@ptrCast(opt), opt.len);
},
*const P2_Affine, *P2_Affine => {
const sigp: [*c]const c.p1_affine = switch (@TypeOf(sig)) {
@TypeOf(null) => null,
else => &sig.point,
};
err = c.pairing_aggregate_pk_in_g2(@ptrCast(self.ctx),
&pk.point, sigp,
@ptrCast(msg), msg.len,
@ptrCast(opt), opt.len);
},
else => |T| @compileError("expected type '*const blst.P1_Affine' "
++ "or '*const blst.P2_Affine', found '"
++ @typeName(T) ++ "'"),
}
return @as(ERROR, @enumFromInt(err));
}
pub fn commit(self: *Pairing) void {
c.pairing_commit(@ptrCast(self.ctx));
}
pub fn merge(self: *Pairing, second: *const Pairing) ERROR {
return c.pairing_merge(@ptrCast(self.ctx), @ptrCast(second.ctx));
}
pub fn finalverify(self: *Pairing, optional: ?*const PT) bool {
return c.pairing_finalverify(@ptrCast(self.ctx), optional);
}
pub fn raw_aggregate(self: *Pairing, q: *const P2_Affine,
p: *const P1_Affine) void {
c.pairing_raw_aggregate(@ptrCast(self.ctx), &q.point, &p.point);
}
pub fn as_fp12(self: *Pairing) *const PT {
return c.pairing_as_fp12(@ptrCast(self.ctx));
}
};
pub const Uniq = struct {
tree: []u64 = &[_]u64{},
allocator: std.mem.Allocator,
pub fn init(n: usize, allocator: std.mem.Allocator) !Uniq {
const nlimbs = (c.uniq_sizeof(n) + @sizeOf(u64) - 1) / @sizeOf(u64);
const buffer = try allocator.alloc(u64, nlimbs);
c.uniq_init(@ptrCast(buffer));
return Uniq{
.tree = buffer,
.allocator = allocator,
};
}
pub fn deinit(self: *Uniq) void {
self.allocator.free(self.tree);
self.tree = &[_]u64{};
}
pub fn is_uniq(self: *Uniq, msg: []const u8) bool {
return c.uniq_test(@ptrCast(self.tree), @ptrCast(msg), msg.len);
}
};
const FP_BYTES = 384/8;
pub const P1_COMPRESS_BYTES = FP_BYTES;
pub const P1_SERIALIZE_BYTES = FP_BYTES*2;
pub const P2_COMPRESS_BYTES = FP_BYTES*2;
pub const P2_SERIALIZE_BYTES = FP_BYTES*4;
pub const P1_Affine = struct {
point: c.p1_affine = c.p1_affine{},
pub fn from(in: anytype) !P1_Affine {
switch (@TypeOf(in)) {
*const P1,
*P1 => return in.to_affine(),
P1 => @compileError("expected type '*const blst.P1', found 'blst.P1'"),
else => |T| {
switch (@typeInfo(T)) {
.pointer => { const s: []const u8 = in; _ = s; },
else => @compileError("expected type '[]const u8', found '" ++ @typeName(T) ++ "'"),
}
var ret: P1_Affine = undefined;
const err = ret.deserialize(in);
return if (err == .SUCCESS) ret else err.as_error();
},
}
unreachable;
}
pub fn deserialize(self: *P1_Affine, in: []const u8) ERROR {
if (in.len == 0) {
return .BAD_ENCODING;
}
const expected = @as(usize, if (in[0]&0x80 != 0) P1_COMPRESS_BYTES
else P1_SERIALIZE_BYTES);
if (in.len != expected) {
return .BAD_ENCODING;
}
const err = c.p1_deserialize(&self.point, &in[0]);
return @as(ERROR, @enumFromInt(err));
}
pub fn serialize(self: *const P1_Affine) [P1_SERIALIZE_BYTES]u8 {
var ret: [P1_SERIALIZE_BYTES]u8 = undefined;
c.p1_affine_serialize(&ret[0], &self.point);
return ret;
}
pub fn compress(self: *const P1_Affine) [P1_COMPRESS_BYTES]u8 {
var ret: [P1_COMPRESS_BYTES]u8 = undefined;
c.p1_affine_compress(&ret[0], &self.point);
return ret;
}
pub fn dup(self: *const P1_Affine) P1_Affine {
return self.*;
}
pub fn on_curve(self: *const P1_Affine) bool {
return c.p1_affine_on_curve(&self.point);
}
pub fn in_group(self: *const P1_Affine) bool {
return c.p1_affine_in_g1(&self.point);
}
pub fn is_inf(self: *const P1_Affine) bool {
return c.p1_affine_is_inf(&self.point);
}
pub fn is_equal(self: *const P1_Affine, p: *const P1_Affine) bool {
return c.p1_affine_is_equal(&self.point, &p.point);
}
pub fn core_verify(self: *const P1_Affine, pk: *const P2_Affine,
hash_or_encode: bool, msg: []const u8, DST: []const u8,
aug: ?[]const u8) ERROR {
const opt = aug orelse &[_]u8{};
const err = c.core_verify_pk_in_g2(&pk.point, &self.point,
hash_or_encode,
@ptrCast(msg), msg.len,
@ptrCast(DST), DST.len,
@ptrCast(opt), opt.len);
return @as(ERROR, @enumFromInt(err));
}
pub fn generator() P1_Affine {
return P1_Affine{
.point = c.p1_affine_generator().*,
};
}
pub fn to_jacobian(self: *const P1_Affine) P1 {
var ret: P1 = undefined;
c.p1_from_affine(&ret.point, &self.point);
return ret;
}
};
pub const P1 = struct {
point: c.p1 = c.p1{},
pub fn from(in: anytype) !P1 {
switch (@TypeOf(in)) {
*const SecretKey,
*SecretKey => return P1.public_key(in),
SecretKey => @compileError("expected type '*const blst.SecretKey', found 'blst.SecretKey'"),
*const P1_Affine,
*P1_Affine => return in.to_jacobian(),
P1_Affine => @compileError("expected type '*const blst.P1_Affine', found 'blst.P1_Affine'"),
else => |T| {
switch (@typeInfo(T)) {
.pointer => { const s: []const u8 = in; _ = s; },
else => @compileError("expected type '[]const u8', found '" ++ @typeName(T) ++ "'"),
}
var ret: P1 = undefined;
const err = ret.deserialize(in);
return if (err == .SUCCESS) ret else err.as_error();
},
}
unreachable;
}
pub fn deserialize(self: *P1, in: []const u8) ERROR {
if (in.len == 0) {
return .BAD_ENCODING;
}
const expected = @as(usize, if (in[0]&0x80 != 0) P1_COMPRESS_BYTES
else P1_SERIALIZE_BYTES);
if (in.len != expected) {
return .BAD_ENCODING;
}
const err = c.p1_deserialize(@ptrCast(&self.point), &in[0]);
if (err == c.SUCCESS) {
c.p1_from_affine(&self.point, @ptrCast(&self.point));
}
return @as(ERROR, @enumFromInt(err));
}
pub fn serialize(self: *const P1) [P1_SERIALIZE_BYTES]u8 {
var ret: [P1_SERIALIZE_BYTES]u8 = undefined;
c.p1_serialize(&ret[0], &self.point);
return ret;
}
pub fn compress(self: *const P1) [P1_COMPRESS_BYTES]u8 {
var ret: [P1_COMPRESS_BYTES]u8 = undefined;
c.p1_compress(&ret[0], &self.point);
return ret;
}
pub fn public_key(sk: *const SecretKey) P1 {
var ret: P1 = undefined;
c.sk_to_pk_in_g1(&ret.point, &sk.key);
return ret;
}
pub fn dup(self: *const P1) P1 {
return self.*;
}
pub fn on_curve(self: *const P1) bool {
return c.p1_on_curve(&self.point);
}
pub fn in_group(self: *const P1) bool {
return c.p1_in_g1(&self.point);
}
pub fn is_inf(self: *const P1) bool {
return c.p1_is_inf(&self.point);
}
pub fn is_equal(self: *const P1, p: *const P1) bool {
return c.p1_is_equal(&self.point, &p.point);
}
pub fn aggregate(self: *P1, p: *const P1_Affine) !void {
if (!c.p1_affine_in_g1(&p.point)) {
return Error.POINT_NOT_IN_GROUP;
}
c.p1_add_or_double_affine(&self.point, &self.point, &p.point);
}
pub fn hash_to(msg: []const u8, DST: []const u8, aug: ?[]const u8) P1 {
const opt = aug orelse &[_]u8{};
var ret: P1 = undefined;
c.hash_to_g1(&ret.point, @ptrCast(msg), msg.len,
@ptrCast(DST), DST.len,
@ptrCast(opt), opt.len);
return ret;
}
pub fn encode_to(msg: []const u8, DST: []const u8, aug: ?[]const u8) P1 {
const opt = aug orelse &[_]u8{};
var ret: P1 = undefined;
c.encode_to_g1(&ret.point, @ptrCast(msg), msg.len,
@ptrCast(DST), DST.len,
@ptrCast(opt), opt.len);
return ret;
}
pub fn sign_with(self: *const P1, sk: *const SecretKey) *P1 {
c.sign_pk_in_g2(@constCast(&self.point), &self.point, &sk.key);
return @constCast(self);
}
pub fn to_affine(self: *const P1) P1_Affine {
var ret: P1_Affine = undefined;
c.p1_to_affine(&ret.point, &self.point);
return ret;
}
pub fn generator() P1 {
return P1{
.point = c.p1_generator().*,
};
}
};
pub const P2_Affine = struct {
point: c.p2_affine = c.p2_affine{},
pub fn from(in: anytype) !P2_Affine {
switch (@TypeOf(in)) {
*const P2,
*P2 => return in.to_affine(),
P2 => @compileError("expected type '*const blst.P2', found 'blst.P2'"),
else => |T| {
switch (@typeInfo(T)) {
.pointer => { const s: []const u8 = in; _ = s; },
else => @compileError("expected type '[]const u8', found '" ++ @typeName(T) ++ "'"),
}
var ret: P2_Affine = undefined;
const err = ret.deserialize(in);
return if (err == .SUCCESS) ret else err.as_error();
},
}
unreachable;
}
pub fn deserialize(self: *P2_Affine, in: []const u8) ERROR {
if (in.len == 0) {
return .BAD_ENCODING;
}
const expected = @as(usize, if (in[0]&0x80 != 0) P2_COMPRESS_BYTES
else P2_SERIALIZE_BYTES);
if (in.len != expected) {
return .BAD_ENCODING;
}
const err = c.p2_deserialize(&self.point, &in[0]);
return @as(ERROR, @enumFromInt(err));
}
pub fn serialize(self: *const P2_Affine) [P2_SERIALIZE_BYTES]u8 {
var ret: [P2_SERIALIZE_BYTES]u8 = undefined;
c.p2_affine_serialize(&ret[0], &self.point);
return ret;
}
pub fn compress(self: *const P2_Affine) [P2_COMPRESS_BYTES]u8 {
var ret: [P2_COMPRESS_BYTES]u8 = undefined;
c.p2_affine_compress(&ret[0], &self.point);
return ret;
}
pub fn dup(self: *const P2_Affine) P2_Affine {
return self.*;
}
pub fn on_curve(self: *const P2_Affine) bool {
return c.p2_affine_on_curve(&self.point);
}
pub fn in_group(self: *const P2_Affine) bool {
return c.p2_affine_in_g2(&self.point);
}
pub fn is_inf(self: *const P2_Affine) bool {
return c.p2_affine_is_inf(&self.point);
}
pub fn is_equal(self: *const P2_Affine, p: *const P2_Affine) bool {
return c.p2_affine_is_equal(&self.point, &p.point);
}
pub fn core_verify(self: *const P2_Affine, pk: *const P1_Affine,
hash_or_encode: bool, msg: []const u8, DST: []const u8,
aug: ?[]const u8) ERROR {
const opt = aug orelse &[_]u8{};
const err = c.core_verify_pk_in_g1(&pk.point, &self.point,
hash_or_encode,
@ptrCast(msg), msg.len,
@ptrCast(DST), DST.len,
@ptrCast(opt), opt.len);
return @as(ERROR, @enumFromInt(err));
}
pub fn generator() P2_Affine {
return P2_Affine{
.point = c.p2_affine_generator().*,
};
}
pub fn to_jacobian(self: *const P2_Affine) P2 {
var ret: P2 = undefined;
c.p2_from_affine(&ret.point, &self.point);
return ret;
}
};
pub const P2 = struct {
point: c.p2 = c.p2{},
pub fn from(in: anytype) !P2 {
switch (@TypeOf(in)) {
*const SecretKey,
*SecretKey => return P2.public_key(in),
SecretKey => @compileError("expected type '*const blst.SecretKey', found 'blst.SecretKey'"),
*const P2_Affine,
*P2_Affine => return in.to_jacobian(),
P2_Affine => @compileError("expected type '*const blst.P2_Affine', found 'blst.P2_Affine'"),
else => |T| {
switch (@typeInfo(T)) {
.pointer => { const s: []const u8 = in; _ = s; },
else => @compileError("expected type '[]const u8', found '" ++ @typeName(T) ++ "'"),
}
var ret: P2 = undefined;
const err = ret.deserialize(in);
return if (err == .SUCCESS) ret else err.as_error();
},
}
unreachable;
}
pub fn deserialize(self: *P2, in: []const u8) ERROR {
if (in.len == 0) {
return .BAD_ENCODING;
}
const expected = @as(usize, if (in[0]&0x80 != 0) P2_COMPRESS_BYTES
else P2_SERIALIZE_BYTES);
if (in.len != expected) {
return .BAD_ENCODING;
}
const err = c.p2_deserialize(@ptrCast(&self.point), &in[0]);
if (err == c.SUCCESS) {
c.p2_from_affine(&self.point, @ptrCast(&self.point));
}
return @as(ERROR, @enumFromInt(err));
}
pub fn serialize(self: *const P2) [P2_SERIALIZE_BYTES]u8 {
var ret: [P2_SERIALIZE_BYTES]u8 = undefined;
c.p2_serialize(&ret[0], &self.point);
return ret;
}
pub fn compress(self: *const P2) [P2_COMPRESS_BYTES]u8 {
var ret: [P2_COMPRESS_BYTES]u8 = undefined;
c.p2_compress(&ret[0], &self.point);
return ret;
}
pub fn public_key(sk: *const SecretKey) P2 {
var ret: P2 = undefined;
c.sk_to_pk_in_g2(&ret.point, &sk.key);
return ret;
}
pub fn dup(self: *const P2) P2 {
return self.*;
}
pub fn on_curve(self: *const P2) bool {
return c.p2_on_curve(&self.point);
}
pub fn in_group(self: *const P2) bool {
return c.p2_in_g2(&self.point);
}
pub fn is_inf(self: *const P2) bool {
return c.p2_is_inf(&self.point);
}
pub fn is_equal(self: *const P2, p: *const P2) bool {
return c.p2_is_equal(&self.point, &p.point);
}
pub fn aggregate(self: *P2, p: *const P2_Affine) !void {
if (!c.p2_affine_in_g2(&p.point)) {
return Error.POINT_NOT_IN_GROUP;
}
c.p2_add_or_double_affine(&self.point, &self.point, &p.point);
}
pub fn hash_to(msg: []const u8, DST: []const u8, aug: ?[]const u8) P2 {
const opt = aug orelse &[_]u8{};
var ret: P2 = undefined;
c.hash_to_g2(&ret.point, @ptrCast(msg), msg.len,
@ptrCast(DST), DST.len,
@ptrCast(opt), opt.len);
return ret;
}
pub fn encode_to(msg: []const u8, DST: []const u8, aug: ?[]const u8) P2 {
const opt = aug orelse &[_]u8{};
var ret: P2 = undefined;
c.encode_to_g2(&ret.point, @ptrCast(msg), msg.len,
@ptrCast(DST), DST.len,
@ptrCast(opt), opt.len);
return ret;
}
pub fn sign_with(self: *const P2, sk: *const SecretKey) *P2 {
c.sign_pk_in_g1(@constCast(&self.point), &self.point, &sk.key);
return @constCast(self);
}
pub fn to_affine(self: *const P2) P2_Affine {
var ret: P2_Affine = undefined;
c.p2_to_affine(&ret.point, &self.point);
return ret;
}
pub fn generator() P2 {
return P2{
.point = c.p2_generator().*,
};
}
};