þ½Ž¿using System;
using System.Text;
using System.Runtime.InteropServices;
namespace mcl {
class BLS256 {
const int IoEcComp = 512; // fixed byte representation
public const int MCLBN_FR_UNIT_SIZE = 4;
public const int MCLBN_FP_UNIT_SIZE = 4;
public const int MCLBN_COMPILED_TIME_VAR = MCLBN_FR_UNIT_SIZE * 10 + MCLBN_FP_UNIT_SIZE;
[DllImport("bls256.dll")]
public static extern int blsInit(int curve, int compiledTimeVar);
[DllImport("bls256.dll")] public static extern void blsIdSetInt(ref Id id, int x);
[DllImport("bls256.dll")] public static extern int blsIdSetDecStr(ref Id id, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize);
[DllImport("bls256.dll")] public static extern int blsIdSetHexStr(ref Id id, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize);
[DllImport("bls256.dll")] public static extern ulong blsIdGetDecStr([Out]StringBuilder buf, ulong maxBufSize, ref Id id);
[DllImport("bls256.dll")] public static extern ulong blsIdGetHexStr([Out]StringBuilder buf, ulong maxBufSize, ref Id id);
[DllImport("bls256.dll")] public static extern ulong blsIdSerialize([Out]StringBuilder buf, ulong maxBufSize, ref Id id);
[DllImport("bls256.dll")] public static extern ulong blsSecretKeySerialize([Out]StringBuilder buf, ulong maxBufSize, ref SecretKey sec);
[DllImport("bls256.dll")] public static extern ulong blsPublicKeySerialize([Out]StringBuilder buf, ulong maxBufSize, ref PublicKey pub);
[DllImport("bls256.dll")] public static extern ulong blsSignatureSerialize([Out]StringBuilder buf, ulong maxBufSize, ref Signature sig);
[DllImport("bls256.dll")] public static extern int blsIdDeserialize(ref Id id, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize);
[DllImport("bls256.dll")] public static extern int blsSecretKeyDeserialize(ref SecretKey sec, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize);
[DllImport("bls256.dll")] public static extern int blsPublicKeyDeserialize(ref PublicKey pub, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize);
[DllImport("bls256.dll")] public static extern int blsSignatureDeserialize(ref Signature sig, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize);
[DllImport("bls256.dll")] public static extern int blsIdIsEqual(ref Id lhs, ref Id rhs);
[DllImport("bls256.dll")] public static extern int blsSecretKeyIsEqual(ref SecretKey lhs, ref SecretKey rhs);
[DllImport("bls256.dll")] public static extern int blsPublicKeyIsEqual(ref PublicKey lhs, ref PublicKey rhs);
[DllImport("bls256.dll")] public static extern int blsSignatureIsEqual(ref Signature lhs, ref Signature rhs);
// add
[DllImport("bls256.dll")] public static extern void blsSecretKeyAdd(ref SecretKey sec, ref SecretKey rhs);
[DllImport("bls256.dll")] public static extern void blsPublicKeyAdd(ref PublicKey pub, ref PublicKey rhs);
[DllImport("bls256.dll")] public static extern void blsSignatureAdd(ref Signature sig, ref Signature rhs);
// hash buf and set
[DllImport("bls256.dll")] public static extern int blsHashToSecretKey(ref SecretKey sec, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize);
/*
set secretKey if system has /dev/urandom or CryptGenRandom
return 0 if success else -1
*/
[DllImport("bls256.dll")] public static extern int blsSecretKeySetByCSPRNG(ref SecretKey sec);
[DllImport("bls256.dll")] public static extern void blsGetPublicKey(ref PublicKey pub, ref SecretKey sec);
[DllImport("bls256.dll")] public static extern void blsGetPop(ref Signature sig, ref SecretKey sec);
// return 0 if success
[DllImport("bls256.dll")] public static extern int blsSecretKeyShare(ref SecretKey sec, ref SecretKey msk, ulong k, ref Id id);
[DllImport("bls256.dll")] public static extern int blsPublicKeyShare(ref PublicKey pub, ref PublicKey mpk, ulong k, ref Id id);
[DllImport("bls256.dll")] public static extern int blsSecretKeyRecover(ref SecretKey sec, ref SecretKey secVec, ref Id idVec, ulong n);
[DllImport("bls256.dll")] public static extern int blsPublicKeyRecover(ref PublicKey pub, ref PublicKey pubVec, ref Id idVec, ulong n);
[DllImport("bls256.dll")] public static extern int blsSignatureRecover(ref Signature sig, ref Signature sigVec, ref Id idVec, ulong n);
[DllImport("bls256.dll")] public static extern void blsSign(ref Signature sig, ref SecretKey sec, [In][MarshalAs(UnmanagedType.LPStr)] string m, ulong size);
// return 1 if valid
[DllImport("bls256.dll")] public static extern int blsVerify(ref Signature sig, ref PublicKey pub, [In][MarshalAs(UnmanagedType.LPStr)] string m, ulong size);
[DllImport("bls256.dll")] public static extern int blsVerifyPop(ref Signature sig, ref PublicKey pub);
//////////////////////////////////////////////////////////////////////////
// the following apis will be removed
// mask buf with (1 << (bitLen(r) - 1)) - 1 if buf >= r
[DllImport("bls256.dll")] public static extern int blsIdSetLittleEndian(ref Id id, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize);
/*
return written byte size if success else 0
*/
[DllImport("bls256.dll")] public static extern ulong blsIdGetLittleEndian([Out]StringBuilder buf, ulong maxBufSize, ref Id id);
// return 0 if success
// mask buf with (1 << (bitLen(r) - 1)) - 1 if buf >= r
[DllImport("bls256.dll")] public static extern int blsSecretKeySetLittleEndian(ref SecretKey sec, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize);
[DllImport("bls256.dll")] public static extern int blsSecretKeySetDecStr(ref SecretKey sec, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize);
[DllImport("bls256.dll")] public static extern int blsSecretKeySetHexStr(ref SecretKey sec, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize);
/*
return written byte size if success else 0
*/
[DllImport("bls256.dll")] public static extern ulong blsSecretKeyGetLittleEndian([Out]StringBuilder buf, ulong maxBufSize, ref SecretKey sec);
/*
return strlen(buf) if success else 0
buf is '\0' terminated
*/
[DllImport("bls256.dll")] public static extern ulong blsSecretKeyGetDecStr([Out]StringBuilder buf, ulong maxBufSize, ref SecretKey sec);
[DllImport("bls256.dll")] public static extern ulong blsSecretKeyGetHexStr([Out]StringBuilder buf, ulong maxBufSize, ref SecretKey sec);
[DllImport("bls256.dll")] public static extern int blsPublicKeySetHexStr(ref PublicKey pub, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize);
[DllImport("bls256.dll")] public static extern ulong blsPublicKeyGetHexStr([Out]StringBuilder buf, ulong maxBufSize, ref PublicKey pub);
[DllImport("bls256.dll")] public static extern int blsSignatureSetHexStr(ref Signature sig, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize);
[DllImport("bls256.dll")] public static extern ulong blsSignatureGetHexStr([Out]StringBuilder buf, ulong maxBufSize, ref Signature sig);
public static void Init()
{
const int CurveFp254BNb = 0;
if (!System.Environment.Is64BitProcess) {
throw new PlatformNotSupportedException("not 64-bit system");
}
int err = blsInit(CurveFp254BNb, MCLBN_COMPILED_TIME_VAR);
if (err != 0) {
throw new ArgumentException("blsInit");
}
}
public struct Id {
private ulong v0, v1, v2, v3;
public bool IsEqual(Id rhs)
{
return blsIdIsEqual(ref this, ref rhs) != 0;
}
public void SetDecStr(String s)
{
if (blsIdSetDecStr(ref this, s, (ulong)s.Length) != 0) {
throw new ArgumentException("blsIdSetDecSt:" + s);
}
}
public void SetHexStr(String s)
{
if (blsIdSetHexStr(ref this, s, (ulong)s.Length) != 0) {
throw new ArgumentException("blsIdSetHexStr:" + s);
}
}
public void SetInt(int x)
{
blsIdSetInt(ref this, x);
}
public string GetDecStr()
{
StringBuilder sb = new StringBuilder(1024);
ulong size = blsIdGetDecStr(sb, (ulong)sb.Capacity, ref this);
if (size == 0) {
throw new ArgumentException("blsIdGetDecStr");
}
return sb.ToString(0, (int)size);
}
public string GetHexStr()
{
StringBuilder sb = new StringBuilder(1024);
ulong size = blsIdGetHexStr(sb, (ulong)sb.Capacity, ref this);
if (size == 0) {
throw new ArgumentException("blsIdGetHexStr");
}
return sb.ToString(0, (int)size);
}
}
public struct SecretKey {
private ulong v0, v1, v2, v3;
public bool IsEqual(SecretKey rhs)
{
return blsSecretKeyIsEqual(ref this, ref rhs) != 0;
}
public void SetHexStr(String s)
{
if (blsSecretKeySetHexStr(ref this, s, (ulong)s.Length) != 0) {
throw new ArgumentException("blsSecretKeySetHexStr:" + s);
}
}
public string GetHexStr()
{
StringBuilder sb = new StringBuilder(1024);
ulong size = blsSecretKeyGetHexStr(sb, (ulong)sb.Capacity, ref this);
if (size == 0) {
throw new ArgumentException("mclBnFr_getStr");
}
return sb.ToString(0, (int)size);
}
public void Add(SecretKey rhs)
{
blsSecretKeyAdd(ref this, ref rhs);
}
public void SetByCSPRNG()
{
blsSecretKeySetByCSPRNG(ref this);
}
public void SetHashOf(string s)
{
if (blsHashToSecretKey(ref this, s, (ulong)s.Length) != 0) {
throw new ArgumentException("blsHashToSecretKey");
}
}
public PublicKey GetPublicKey()
{
PublicKey pub = new PublicKey();
blsGetPublicKey(ref pub, ref this);
return pub;
}
public Signature Signature(String m)
{
Signature Signature = new Signature();
blsSign(ref Signature, ref this, m, (ulong)m.Length);
return Signature;
}
}
// secretKey = sum_{i=0}^{msk.Length - 1} msk[i] * id^i
public static SecretKey ShareSecretKey(SecretKey[] msk, Id id)
{
SecretKey sec = new SecretKey();
if (blsSecretKeyShare(ref sec, ref msk[0], (ulong)msk.Length, ref id) != 0) {
throw new ArgumentException("GetSecretKeyForId:" + id.ToString());
}
return sec;
}
public static SecretKey RecoverSecretKey(SecretKey[] secs, Id[] ids)
{
SecretKey sec = new SecretKey();
if (blsSecretKeyRecover(ref sec, ref secs[0], ref ids[0], (ulong)secs.Length) != 0) {
throw new ArgumentException("Recover");
}
return sec;
}
public struct PublicKey {
private ulong v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11;
private ulong v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23;
public bool IsEqual(PublicKey rhs)
{
return blsPublicKeyIsEqual(ref this, ref rhs) != 0;
}
public void SetStr(String s)
{
if (blsPublicKeySetHexStr(ref this, s, (ulong)s.Length) != 0) {
throw new ArgumentException("blsPublicKeySetStr:" + s);
}
}
public string GetHexStr()
{
StringBuilder sb = new StringBuilder(1024);
ulong size = blsPublicKeyGetHexStr(sb, (ulong)sb.Capacity, ref this);
if (size == 0) {
throw new ArgumentException("blsPublicKeyGetStr");
}
return sb.ToString(0, (int)size);
}
public void Add(PublicKey rhs)
{
blsPublicKeyAdd(ref this, ref rhs);
}
public bool Verify(Signature Signature, string m)
{
return blsVerify(ref Signature, ref this, m, (ulong)m.Length) == 1;
}
}
// publicKey = sum_{i=0}^{mpk.Length - 1} mpk[i] * id^i
public static PublicKey SharePublicKey(PublicKey[] mpk, Id id)
{
PublicKey pub = new PublicKey();
if (blsPublicKeyShare(ref pub, ref mpk[0], (ulong)mpk.Length, ref id) != 0) {
throw new ArgumentException("GetPublicKeyForId:" + id.ToString());
}
return pub;
}
public static PublicKey RecoverPublicKey(PublicKey[] pubs, Id[] ids)
{
PublicKey pub = new PublicKey();
if (blsPublicKeyRecover(ref pub, ref pubs[0], ref ids[0], (ulong)pubs.Length) != 0) {
throw new ArgumentException("Recover");
}
return pub;
}
public struct Signature {
private ulong v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11;
public bool IsEqual(Signature rhs)
{
return blsSignatureIsEqual(ref this, ref rhs) != 0;
}
public void SetStr(String s)
{
if (blsSignatureSetHexStr(ref this, s, (ulong)s.Length) != 0) {
throw new ArgumentException("blsSignatureSetStr:" + s);
}
}
public string GetHexStr()
{
StringBuilder sb = new StringBuilder(1024);
ulong size = blsSignatureGetHexStr(sb, (ulong)sb.Capacity, ref this);
if (size == 0) {
throw new ArgumentException("blsSignatureGetStr");
}
return sb.ToString(0, (int)size);
}
public void Add(Signature rhs)
{
blsSignatureAdd(ref this, ref rhs);
}
}
public static Signature RecoverSign(Signature[] signs, Id[] ids)
{
Signature Signature = new Signature();
if (blsSignatureRecover(ref Signature, ref signs[0], ref ids[0], (ulong)signs.Length) != 0) {
throw new ArgumentException("Recover");
}
return Signature;
}
}
}