þ½Ž¿using System; using System.Text; using System.Runtime.InteropServices; namespace mcl { class BLS256 { const int IoEcComp = 512; // fixed byte representation public const int maxUnitSize = 4; [DllImport("bls256.dll")] public static extern int blsInit(int curve, int maxUnitSize); [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, maxUnitSize); 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; } } }