Files

826 lines
34 KiB
Plaintext
Executable File

#!/usr/bin/env python3
# Copyright Supranational LLC
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
import os
import re
import sys
import glob
import subprocess
top = """
using System;
using System.Text;
using System.Numerics;
using System.Runtime.InteropServices;
using size_t = System.UIntPtr;
#if NET5_0_OR_GREATER
using System.Runtime.Loader;
using System.Reflection;
using System.IO;
#endif
namespace supranational { public static class blst {
#if NET5_0_OR_GREATER
private static readonly string dll;
static blst()
{
if (String.IsNullOrEmpty(dll)) {
var name = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "blst.dll"
: RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "libblst.dll.dylib"
: "libblst.dll.so";
var dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var arch = RuntimeInformation.ProcessArchitecture switch {
Architecture.X64 => "x64",
Architecture.Arm64 => "arm64",
_ => "unsupported"
};
#if NET8_0_OR_GREATER
// RuntimeInformation.RuntimeIdentifier changed between .NET 7 and 8
// and only aligns to the nuget layout in 8+
var rid = RuntimeInformation.RuntimeIdentifier;
#else
// Mimic pre-8 RuntimeInformation.RuntimeIdentifier as
// "win-x64", "linux-x64", "linux-arm64", "osx-x64", etc.
var os = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "win"
: RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "osx"
: RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD) ? "freebsd"
: "linux";
var rid = $"{os}-{arch}";
#endif
// first look for the file in the standard locations for a nuget installed native lib
dll = Path.Combine(dir, "runtimes", rid, "native", name);
if (!File.Exists(dll))
dll = Path.Combine(dir, arch, name); // try the original non-standard location
if (!File.Exists(dll))
dll = Path.Combine(Environment.CurrentDirectory, name);
if (File.Exists(dll)) {
AssemblyLoadContext.Default.ResolvingUnmanagedDll += (asm, needs) =>
(needs == "blst.dll" ? NativeLibrary.Load(dll) : IntPtr.Zero);
}
}
}
#endif
public enum ERROR {
SUCCESS = 0,
BAD_ENCODING,
POINT_NOT_ON_CURVE,
POINT_NOT_IN_GROUP,
AGGR_TYPE_MISMATCH,
VERIFY_FAIL,
PK_IS_INFINITY,
BAD_SCALAR,
}
public class Exception : ApplicationException {
private readonly ERROR code;
public Exception(ERROR err) { code = err; }
public override string Message
{ get
{ switch(code) {
case ERROR.BAD_ENCODING: return "bad encoding";
case ERROR.POINT_NOT_ON_CURVE: return "point not on curve";
case ERROR.POINT_NOT_IN_GROUP: return "point not in group";
case ERROR.AGGR_TYPE_MISMATCH: return "aggregate type mismatch";
case ERROR.VERIFY_FAIL: return "verify failure";
case ERROR.PK_IS_INFINITY: return "public key is infinity";
case ERROR.BAD_SCALAR: return "bad scalar";
default: return null;
}
}
}
}
public enum ByteOrder {
BigEndian,
LittleEndian,
}
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_keygen([Out] byte[] key, [In] byte[] IKM, size_t IKM_len,
[In] byte[] info, size_t info_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_keygen_v3([Out] byte[] key, [In] byte[] IKM, size_t IKM_len,
[In] byte[] info, size_t info_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_keygen_v4_5([Out] byte[] key, [In] byte[] IKM, size_t IKM_len,
[In] byte[] salt, size_t salt_len,
[In] byte[] info, size_t info_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_keygen_v5([Out] byte[] key, [In] byte[] IKM, size_t IKM_len,
[In] byte[] salt, size_t salt_len,
[In] byte[] info, size_t info_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_derive_master_eip2333([Out] byte[] key,
[In] byte[] IKM, size_t IKM_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_derive_child_eip2333([Out] byte[] key,
[In] byte[] master, uint child_index);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_scalar_from_bendian([Out] byte[] ret, [In] byte[] key);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_bendian_from_scalar([Out] byte[] ret, [In] byte[] key);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_sk_check([In] byte[] key);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_scalar_from_lendian([Out] byte[] key, [In] byte[] inp);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_lendian_from_scalar([Out] byte[] key, [In] byte[] inp);
public struct SecretKey {
internal byte[] key;
//public SecretKey() { key = new byte[32]; }
public SecretKey(byte[] IKM, string info)
{ key = new byte[32]; keygen(IKM, info); }
public SecretKey(byte[] inp, ByteOrder order=ByteOrder.BigEndian)
{ key = new byte[32];
switch(order) {
case ByteOrder.BigEndian: from_bendian(inp); break;
case ByteOrder.LittleEndian: from_lendian(inp); break;
}
}
public void keygen(byte[] IKM, string info="")
{ if (key == null) key = new byte[32];
byte[] info_bytes = Encoding.UTF8.GetBytes(info);
blst_keygen(key, IKM, (size_t)IKM.Length,
info_bytes, (size_t)info_bytes.Length);
}
public void keygen_v3(byte[] IKM, string info="")
{ if (key == null) key = new byte[32];
byte[] info_bytes = Encoding.UTF8.GetBytes(info);
blst_keygen_v3(key, IKM, (size_t)IKM.Length,
info_bytes, (size_t)info_bytes.Length);
}
public void keygen_v4_5(byte[] IKM, string salt, string info="")
{ if (key == null) key = new byte[32];
byte[] salt_bytes = Encoding.UTF8.GetBytes(salt);
byte[] info_bytes = Encoding.UTF8.GetBytes(info);
blst_keygen_v4_5(key, IKM, (size_t)IKM.Length,
salt_bytes, (size_t)salt_bytes.Length,
info_bytes, (size_t)info_bytes.Length);
}
public void keygen_v5(byte[] IKM, byte[] salt, string info="")
{ if (key == null) key = new byte[32];
byte[] info_bytes = Encoding.UTF8.GetBytes(info);
blst_keygen_v5(key, IKM, (size_t)IKM.Length,
salt, (size_t)salt.Length,
info_bytes, (size_t)info_bytes.Length);
}
public void keygen_v5(byte[] IKM, string salt, string info="")
{ keygen_v5(IKM, Encoding.UTF8.GetBytes(salt), info); }
public void derive_master_eip2333(byte[] IKM)
{ if (key == null) key = new byte[32];
blst_derive_master_eip2333(key, IKM, (size_t)IKM.Length);
}
public SecretKey(SecretKey master, uint child_index)
{ key = new byte[32];
blst_derive_child_eip2333(key, master.key, child_index);
}
public void from_bendian(byte[] inp)
{ if (inp.Length != 32)
throw new Exception(ERROR.BAD_ENCODING);
if (key == null) key = new byte[32];
blst_scalar_from_bendian(key, inp);
if (!blst_sk_check(key))
throw new Exception(ERROR.BAD_ENCODING);
}
public void from_lendian(byte[] inp)
{ if (inp.Length != 32)
throw new Exception(ERROR.BAD_ENCODING);
if (key == null) key = new byte[32];
blst_scalar_from_lendian(key, inp);
if (!blst_sk_check(key))
throw new Exception(ERROR.BAD_ENCODING);
}
public byte[] to_bendian()
{ byte[] ret = new byte[32];
blst_bendian_from_scalar(ret, key);
return ret;
}
public byte[] to_lendian()
{ byte[] ret = new byte[32];
blst_lendian_from_scalar(ret, key);
return ret;
}
}
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_scalar_from_be_bytes([Out] byte[] ret, [In] byte[] inp,
size_t inp_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_scalar_from_le_bytes([Out] byte[] ret, [In] byte[] inp,
size_t inp_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_sk_add_n_check([Out] byte[] ret, [In] byte[] a,
[In] byte[] b);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_sk_sub_n_check([Out] byte[] ret, [In] byte[] a,
[In] byte[] b);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_sk_mul_n_check([Out] byte[] ret, [In] byte[] a,
[In] byte[] b);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_sk_inverse([Out] byte[] ret, [In] byte[] a);
public struct Scalar {
internal byte[] val;
//public Scalar() { val = new byte[32]; }
public Scalar(byte[] inp, ByteOrder order=ByteOrder.BigEndian)
{ val = new byte[32];
switch(order) {
case ByteOrder.BigEndian: from_bendian(inp); break;
case ByteOrder.LittleEndian: from_lendian(inp); break;
}
}
private Scalar(bool _) { val = new byte[32]; }
private Scalar(Scalar orig) { val = (byte[])orig.val.Clone(); }
public Scalar dup() { return new Scalar(this); }
public void from_bendian(byte[] inp)
{ if (val == null) val = new byte[32];
blst_scalar_from_be_bytes(val, inp, (size_t)inp.Length);
}
public void from_lendian(byte[] inp)
{ if (val == null) val = new byte[32];
blst_scalar_from_le_bytes(val, inp, (size_t)inp.Length);
}
public byte[] to_bendian()
{ byte[] ret = new byte[32];
blst_bendian_from_scalar(ret, val);
return ret;
}
public byte[] to_lendian()
{ byte[] ret = new byte[32];
blst_lendian_from_scalar(ret, val);
return ret;
}
public Scalar add(SecretKey a)
{ if (!blst_sk_add_n_check(val, val, a.key))
throw new Exception(ERROR.BAD_SCALAR);
return this;
}
public Scalar add(Scalar a)
{ if (!blst_sk_add_n_check(val, val, a.val))
throw new Exception(ERROR.BAD_SCALAR);
return this;
}
public Scalar sub(Scalar a)
{ if (!blst_sk_sub_n_check(val, val, a.val))
throw new Exception(ERROR.BAD_SCALAR);
return this;
}
public Scalar mul(Scalar a)
{ if (!blst_sk_mul_n_check(val, val, a.val))
throw new Exception(ERROR.BAD_SCALAR);
return this;
}
public Scalar inverse()
{ blst_sk_inverse(val, val); return this; }
public static Scalar operator+(Scalar a, Scalar b)
{ return a.dup().add(b); }
public static Scalar operator-(Scalar a, Scalar b)
{ return a.dup().sub(b); }
public static Scalar operator*(Scalar a, Scalar b)
{ return a.dup().mul(b); }
public static Scalar operator/(Scalar a, Scalar b)
{ return b.dup().inverse().mul(a); }
}
private const int P1_COMPRESSED_SZ = 384/8;
private const int P2_COMPRESSED_SZ = 2*P1_COMPRESSED_SZ;
"""
middle = """
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern size_t blst_p1_affine_sizeof();
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern ERROR blst_p1_deserialize([Out] long[] ret, [In] byte[] inp);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_p1_affine_serialize([Out] byte[] ret, [In] long[] inp);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_p1_affine_compress([Out] byte[] ret, [In] long[] inp);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_p1_to_affine([Out] long[] ret, [In] long[] inp);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_p1_affine_on_curve([In] long[] point);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_p1_affine_in_g1([In] long[] point);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_p1_affine_is_inf([In] long[] point);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_p1_affine_is_equal([In] long[] a, [In] long[] b);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr blst_p1_generator();
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern ERROR blst_core_verify_pk_in_g2([In] long[] pk, [In] long[] sig,
bool hash_or_encode,
[In] byte[] msg, size_t msg_len,
[In] byte[] dst, size_t dst_len,
[In] byte[] aug, size_t aug_len);
public struct P1_Affine {
internal readonly long[] point;
private static readonly int sz = (int)blst_p1_affine_sizeof()/sizeof(long);
//public P1_Affine() { point = new long[sz]; }
private P1_Affine(bool _) { point = new long[sz]; }
private P1_Affine(P1_Affine p) { point = (long[])p.point.Clone(); }
public P1_Affine(byte[] inp) : this(true)
{ int len = inp.Length;
if (len == 0 || len != ((inp[0]&0x80) == 0x80 ? P1_COMPRESSED_SZ
: 2*P1_COMPRESSED_SZ))
throw new Exception(ERROR.BAD_ENCODING);
ERROR err = blst_p1_deserialize(point, inp);
if (err != ERROR.SUCCESS)
throw new Exception(err);
}
public P1_Affine(P1 jacobian) : this(true)
{ blst_p1_to_affine(point, jacobian.point); }
public P1_Affine dup() { return new P1_Affine(this); }
public P1 to_jacobian() { return new P1(this); }
public byte[] serialize()
{ byte[] ret = new byte[2*P1_COMPRESSED_SZ];
blst_p1_affine_serialize(ret, point);
return ret;
}
public byte[] compress()
{ byte[] ret = new byte[P1_COMPRESSED_SZ];
blst_p1_affine_compress(ret, point);
return ret;
}
public bool on_curve() { return blst_p1_affine_on_curve(point); }
public bool in_group() { return blst_p1_affine_in_g1(point); }
public bool is_inf() { return blst_p1_affine_is_inf(point); }
public bool is_equal(P1_Affine p)
{ return blst_p1_affine_is_equal(point, p.point); }
ERROR core_verify(P2_Affine pk, bool hash_or_encode,
byte[] msg, string DST = "", byte[] aug = null)
{ byte[] dst = Encoding.UTF8.GetBytes(DST);
return blst_core_verify_pk_in_g2(pk.point, point,
hash_or_encode,
msg, (size_t)msg.Length,
dst, (size_t)dst.Length,
aug, (size_t)(aug!=null ? aug.Length : 0));
}
public static P1_Affine generator()
{ var ret = new P1_Affine(true);
Marshal.Copy(blst_p1_generator(), ret.point, 0, ret.point.Length);
return ret;
}
}
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern size_t blst_p1_sizeof();
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_p1_serialize([Out] byte[] ret, [In] long[] inp);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_p1_compress([Out] byte[] ret, [In] long[] inp);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_p1_from_affine([Out] long[] ret, [In] long[] inp);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_p1_on_curve([In] long[] point);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_p1_in_g1([In] long[] point);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_p1_is_inf([In] long[] point);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_p1_is_equal([In] long[] a, [In] long[] b);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_sk_to_pk_in_g1([Out] long[] ret, [In] byte[] SK);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_encode_to_g1([Out] long[] ret, [In] byte[] msg, size_t msg_len,
[In] byte[] dst, size_t dst_len,
[In] byte[] aug, size_t aug_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_hash_to_g1([Out] long[] ret, [In] byte[] msg, size_t msg_len,
[In] byte[] dst, size_t dst_len,
[In] byte[] aug, size_t aug_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_sign_pk_in_g2([Out] long[] ret, [In] long[] hash, [In] byte[] SK);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_p1_mult([Out] long[] ret, [In] long[] a,
[In] byte[] scalar, size_t nbits);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_p1_cneg([Out] long[] ret, bool cbit);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_p1_add_or_double([Out] long[] ret, [In] long[] a, [In] long[] b);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_p1_add_or_double_affine([Out] long[] ret, [In] long[] a,
[In] long[] b);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_p1_double([Out] long[] ret, [In] long[] a);
public struct P1 {
internal long[] point;
private static readonly int sz = (int)blst_p1_sizeof()/sizeof(long);
//public P1() { point = new long[sz]; }
private P1(bool _) { point = new long[sz]; }
private P1(P1 p) { point = (long[])p.point.Clone(); }
private long[] self()
{ if (point==null) { point = new long[sz]; } return point; }
public P1(SecretKey sk) : this(true)
{ blst_sk_to_pk_in_g1(point, sk.key); }
public P1(byte[] inp) : this(true)
{ int len = inp.Length;
if (len == 0 || len != ((inp[0]&0x80) == 0x80 ? P1_COMPRESSED_SZ
: 2*P1_COMPRESSED_SZ))
throw new Exception(ERROR.BAD_ENCODING);
ERROR err = blst_p1_deserialize(point, inp);
if (err != ERROR.SUCCESS)
throw new Exception(err);
blst_p1_from_affine(point, point);
}
public P1(P1_Affine affine) : this(true)
{ blst_p1_from_affine(point, affine.point); }
public P1 dup() { return new P1(this); }
public P1_Affine to_affine() { return new P1_Affine(this); }
public byte[] serialize()
{ byte[] ret = new byte[2*P1_COMPRESSED_SZ];
blst_p1_serialize(ret, point);
return ret;
}
public byte[] compress()
{ byte[] ret = new byte[P1_COMPRESSED_SZ];
blst_p1_compress(ret, point);
return ret;
}
public bool on_curve() { return blst_p1_on_curve(point); }
public bool in_group() { return blst_p1_in_g1(point); }
public bool is_inf() { return blst_p1_is_inf(point); }
public bool is_equal(P1 p) { return blst_p1_is_equal(point, p.point); }
public P1 hash_to(byte[] msg, string DST="", byte[] aug=null)
{ byte[] dst = Encoding.UTF8.GetBytes(DST);
blst_hash_to_g1(self(), msg, (size_t)msg.Length,
dst, (size_t)dst.Length,
aug, (size_t)(aug!=null ? aug.Length : 0));
return this;
}
public P1 encode_to(byte[] msg, string DST="", byte[] aug=null)
{ byte[] dst = Encoding.UTF8.GetBytes(DST);
blst_encode_to_g1(self(), msg, (size_t)msg.Length,
dst, (size_t)dst.Length,
aug, (size_t)(aug!=null ? aug.Length : 0));
return this;
}
public P1 sign_with(SecretKey sk)
{ blst_sign_pk_in_g2(point, point, sk.key); return this; }
public P1 sign_with(Scalar scalar)
{ blst_sign_pk_in_g2(point, point, scalar.val); return this; }
public void aggregate(P1_Affine inp)
{ if (blst_p1_affine_in_g1(inp.point))
blst_p1_add_or_double_affine(point, point, inp.point);
else
throw new Exception(ERROR.POINT_NOT_IN_GROUP);
}
public P1 mult(byte[] scalar)
{ blst_p1_mult(point, point, scalar, (size_t)(scalar.Length*8));
return this;
}
public P1 mult(Scalar scalar)
{ blst_p1_mult(point, point, scalar.val, (size_t)255);
return this;
}
public P1 mult(BigInteger scalar)
{ byte[] val;
if (scalar.Sign < 0) {
val = BigInteger.Negate(scalar).ToByteArray();
blst_p1_cneg(point, true);
} else {
val = scalar.ToByteArray();
}
int len = val.Length;
if (val[len-1]==0) len--;
blst_p1_mult(point, point, val, (size_t)(len*8));
return this;
}
public P1 cneg(bool flag) { blst_p1_cneg(point, flag); return this; }
public P1 neg() { blst_p1_cneg(point, true); return this; }
public P1 add(P1 a)
{ blst_p1_add_or_double(point, point, a.point); return this; }
public P1 add(P1_Affine a)
{ blst_p1_add_or_double_affine(point, point, a.point); return this; }
public P1 dbl()
{ blst_p1_double(point, point); return this; }
public static P1 generator()
{ var ret = new P1(true);
Marshal.Copy(blst_p1_generator(), ret.point, 0, ret.point.Length);
return ret;
}
}
public static P1 G1() { return P1.generator(); }
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_aggregated_in_g1([Out] long[] fp12, [In] long[] p);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern ERROR blst_pairing_aggregate_pk_in_g1([In, Out] long[] fp12,
[In] long[] pk, [In] long[] sig,
[In] byte[] msg, size_t msg_len,
[In] byte[] aug, size_t aug_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern ERROR blst_pairing_mul_n_aggregate_pk_in_g1([In, Out] long[] fp12,
[In] long[] pk, [In] long[] sig,
[In] byte[] scalar, size_t nbits,
[In] byte[] msg, size_t msg_len,
[In] byte[] aug, size_t aug_len);
"""
bottom = """
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern size_t blst_fp12_sizeof();
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_miller_loop([Out] long[] fp12, [In] long[] q,
[In] long[] p);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_fp12_is_one([In] long[] fp12);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_fp12_is_equal([In] long[] a, [In] long[] b);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_fp12_sqr([Out] long[] ret, [In] long[] a);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_fp12_mul([Out] long[] ret, [In] long[] a,
[In] long[] b);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_final_exp([Out] long[] ret, [In] long[] a);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_fp12_finalverify([In] long[] a, [In] long[] b);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr blst_fp12_one();
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_fp12_in_group([In] long[] a);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_bendian_from_fp12([Out] byte[] ret, [In] long[] a);
public struct PT {
internal readonly long[] fp12;
private static readonly int sz = (int)blst_fp12_sizeof()/sizeof(long);
internal PT(bool _) { fp12 = new long[sz]; }
private PT(PT orig) { fp12 = (long[])orig.fp12.Clone(); }
public PT(P1_Affine p) : this(true)
{ blst_aggregated_in_g1(fp12, p.point); }
public PT(P1 p) : this(true)
{ blst_aggregated_in_g1(fp12, (new P1_Affine(p)).point); }
public PT(P2_Affine q) : this(true)
{ blst_aggregated_in_g2(fp12, q.point); }
public PT(P2 q) : this(true)
{ blst_aggregated_in_g2(fp12, (new P2_Affine(q)).point); }
public PT(P2_Affine q, P1_Affine p) : this(true)
{ blst_miller_loop(fp12, q.point, p.point); }
public PT(P1_Affine p, P2_Affine q) : this(q, p) {}
public PT(P2 q, P1 p) : this(true)
{ blst_miller_loop(fp12, (new P2_Affine(q)).point,
(new P1_Affine(p)).point);
}
public PT(P1 p, P2 q) : this(q, p) {}
public PT dup() { return new PT(this); }
public bool is_one() { return blst_fp12_is_one(fp12); }
public bool is_equal(PT p)
{ return blst_fp12_is_equal(fp12, p.fp12); }
public PT sqr() { blst_fp12_sqr(fp12, fp12); return this; }
public PT mul(PT p) { blst_fp12_mul(fp12, fp12, p.fp12); return this; }
public PT final_exp() { blst_final_exp(fp12, fp12); return this; }
public bool in_group() { return blst_fp12_in_group(fp12); }
public byte[] to_bendian()
{ byte[] ret = new byte[12*P1_COMPRESSED_SZ];
blst_bendian_from_fp12(ret, fp12);
return ret;
}
public static bool finalverify(PT gt1, PT gt2)
{ return blst_fp12_finalverify(gt1.fp12, gt2.fp12); }
public static PT one()
{ var ret = new PT(true);
Marshal.Copy(blst_fp12_one(), ret.fp12, 0, ret.fp12.Length);
return ret;
}
}
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern size_t blst_pairing_sizeof();
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_pairing_init([In, Out] long[] ctx, bool hash_or_encode,
[In] ref long dst, size_t dst_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_pairing_commit([In, Out] long[] ctx);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern ERROR blst_pairing_merge([In, Out] long[] ctx, [In] long[] ctx1);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_pairing_finalverify([In] long[] ctx, [In] long[] sig);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_pairing_raw_aggregate([In, Out] long[] ctx, [In] long[] q,
[In] long[] p);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr blst_pairing_as_fp12([In] long[] ctx);
public struct Pairing {
private readonly long[] ctx;
private static readonly int sz = (int)blst_pairing_sizeof()/sizeof(long);
public Pairing(bool hash_or_encode=false, string DST="")
{
byte[] dst = Encoding.UTF8.GetBytes(DST);
int dst_len = dst.Length;
int add_len = dst_len!=0 ? (dst_len+sizeof(long)-1)/sizeof(long) : 1;
Array.Resize(ref dst, add_len*sizeof(long));
ctx = new long[sz+add_len];
for (int i=0; i<add_len; i++)
ctx[sz+i] = BitConverter.ToInt64(dst, i*sizeof(long));
GCHandle h = GCHandle.Alloc(ctx, GCHandleType.Pinned);
blst_pairing_init(ctx, hash_or_encode, ref ctx[sz], (size_t)dst_len);
h.Free();
}
public ERROR aggregate(P1_Affine pk, Nullable<P2_Affine> sig,
byte[] msg, byte[] aug=null)
{ return blst_pairing_aggregate_pk_in_g1(ctx, pk.point,
sig.HasValue ? sig.Value.point : null,
msg, (size_t)msg.Length,
aug, (size_t)(aug!=null ? aug.Length : 0));
}
public ERROR aggregate(P2_Affine pk, Nullable<P1_Affine> sig,
byte[] msg, byte[] aug=null)
{ return blst_pairing_aggregate_pk_in_g2(ctx, pk.point,
sig.HasValue ? sig.Value.point : null,
msg, (size_t)msg.Length,
aug, (size_t)(aug!=null ? aug.Length : 0));
}
public ERROR mul_n_aggregate(P2_Affine pk, P1_Affine sig,
byte[] scalar, int nbits,
byte[] msg, byte[] aug=null)
{ return blst_pairing_mul_n_aggregate_pk_in_g2(ctx, pk.point, sig.point,
scalar, (size_t)nbits,
msg, (size_t)msg.Length,
aug, (size_t)(aug!=null ? aug.Length : 0));
}
public ERROR mul_n_aggregate(P1_Affine pk, P2_Affine sig,
byte[] scalar, int nbits,
byte[] msg, byte[] aug=null)
{ return blst_pairing_mul_n_aggregate_pk_in_g1(ctx, pk.point, sig.point,
scalar, (size_t)nbits,
msg, (size_t)msg.Length,
aug, (size_t)(aug!=null ? aug.Length : 0));
}
public void commit() { blst_pairing_commit(ctx); }
public void merge(Pairing a)
{ var err = blst_pairing_merge(ctx, a.ctx);
if (err != ERROR.SUCCESS)
throw new Exception(err);
}
public bool finalverify(PT sig=new PT())
{ return blst_pairing_finalverify(ctx, sig.fp12); }
public void raw_aggregate(P2_Affine q, P1_Affine p)
{ blst_pairing_raw_aggregate(ctx, q.point, p.point); }
public void raw_aggregate(P1_Affine p, P2_Affine q)
{ raw_aggregate(q, p); }
public void raw_aggregate(P2 q, P1 p)
{ blst_pairing_raw_aggregate(ctx, (new P2_Affine(q)).point,
(new P1_Affine(p)).point);
}
public void raw_aggregate(P1 p, P2 q)
{ raw_aggregate(q, p); }
public PT as_fp12()
{ var ret = new PT(true);
GCHandle h = GCHandle.Alloc(ctx, GCHandleType.Pinned);
Marshal.Copy(blst_pairing_as_fp12(ctx), ret.fp12, 0, ret.fp12.Length);
h.Free();
return ret;
}
}
}}"""
here = re.split(r'[/\\](?=[^/\\]*$)', sys.argv[0])
if len(here) > 1:
os.chdir(here[0])
def xchg_1vs2(matchobj):
if matchobj.group(2) == '1':
return matchobj.group(1) + '2'
else:
return matchobj.group(1) + '1'
def newer(files):
if len(files) == 1:
return True
rh = files[-1]
if not os.path.exists(rh):
return True
for lh in files[:-1]:
if os.stat(lh).st_ctime > os.stat(rh).st_ctime:
return True
return False
fname = "supranational.blst.cs"
if newer([here[-1], fname]):
fd = open(fname, "w")
print("//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", file=fd)
print("// DO NOT EDIT THIS FILE!!!", file=fd)
print("// The file is auto-generated by " + here[-1], file=fd)
print("//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", file=fd)
print("\n\n", file=fd)
print(top, file=fd)
print(middle, file=fd)
print(re.sub(r'((?<!f)[pgPG])([12])', xchg_1vs2, middle), file=fd)
print(bottom, file=fd)
fd.close()
try: # mono-devel on Linux ["-language:5" corresponds to latest ECMA/ISO]
subprocess.check_call(["mcs", "-langversion:5", "-optimize+",
"poc.cs", fname, "-r:System.Numerics.dll"])
if newer(["../blst.h"] + glob.glob("libblst.dll.*")):
print("building libblst.dll...") or sys.stdout.flush()
subprocess.check_call(["../../build.sh", "-dll"] + sys.argv[1:])
subprocess.check_call(["mono", "poc.exe"])
sys.exit(0)
except OSError as e:
if e.errno != 2: # not "no such file or directory"
raise e
try: # Visual Studio Developer Command Prompt
subprocess.check_call(["csc", "-langversion:5", "-optimize+",
"poc.cs", fname, "-r:System.Numerics.dll"])
if newer([os.path.normpath("../blst.h"), "blst.dll"]):
print("building blst.dll...") or sys.stdout.flush()
subprocess.check_call([os.path.normpath("../../build.bat"), "-shared"]
+ sys.argv[1:])
subprocess.check_call(os.path.normpath("./poc.exe"))
sys.exit(0)
except OSError as e:
if e.errno != 2: # not "no such file or directory"
raise e
# env = os.environ.copy()
# env["PATH"] = os.getcwd() + os.path.pathsep + env["PATH"]
# env["DYLD_FALLBACK_LIBRARY_PATH"] = os.getcwd()
# env["LD_LIBRARY_PATH"] = os.getcwd()
# subprocess.check_call(["dotnet", "run"], env=env)