commit
42fc50a240
@ -0,0 +1,680 @@ |
||||
þ½Ž¿using System; |
||||
using System.Text; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
namespace mcl { |
||||
public class MCL { |
||||
public const int BN254 = 0; |
||||
public const int BN_SNARK = 4; |
||||
public const int BLS12_381 = 5; |
||||
public const int MCL_MAP_TO_MODE_HASH_TO_CURVE = 5; |
||||
public const int FR_UNIT_SIZE = 4; |
||||
public const int FP_UNIT_SIZE = 6; // 4 if mclbn256.dll is used |
||||
|
||||
public const int G1_UNIT_SIZE = FP_UNIT_SIZE * 3; |
||||
public const int G2_UNIT_SIZE = FP_UNIT_SIZE * 2 * 3; |
||||
public const int GT_UNIT_SIZE = FP_UNIT_SIZE * 12; |
||||
|
||||
public const string dllName = "mclbn384_256"; |
||||
[DllImport(dllName)] public static extern int mclBn_init(int curve, int compiledTimeVar); |
||||
[DllImport(dllName)] public static extern void mclBn_setETHserialization(int enable); |
||||
[DllImport(dllName)] public static extern int mclBn_setMapToMode(int mode); |
||||
[DllImport(dllName)] public static extern void mclBnFr_clear(ref Fr x); |
||||
[DllImport(dllName)] public static extern void mclBnFr_setInt(ref Fr y, int x); |
||||
[DllImport(dllName)] public static extern int mclBnFr_setStr(ref Fr x, [In][MarshalAs(UnmanagedType.LPStr)] string buf, long bufSize, int ioMode); |
||||
[DllImport(dllName)] public static extern int mclBnFr_isValid(in Fr x); |
||||
[DllImport(dllName)] public static extern int mclBnFr_isEqual(in Fr x, in Fr y); |
||||
[DllImport(dllName)] public static extern int mclBnFr_isZero(in Fr x); |
||||
[DllImport(dllName)] public static extern int mclBnFr_isOne(in Fr x); |
||||
[DllImport(dllName)] public static extern void mclBnFr_setByCSPRNG(ref Fr x); |
||||
|
||||
[DllImport(dllName)] public static extern int mclBnFr_setHashOf(ref Fr x, [In][MarshalAs(UnmanagedType.LPStr)] string buf, long bufSize); |
||||
[DllImport(dllName)] public static extern int mclBnFr_getStr([Out] StringBuilder buf, long maxBufSize, in Fr x, int ioMode); |
||||
|
||||
[DllImport(dllName)] public static extern void mclBnFr_neg(ref Fr y, in Fr x); |
||||
[DllImport(dllName)] public static extern void mclBnFr_inv(ref Fr y, in Fr x); |
||||
[DllImport(dllName)] public static extern void mclBnFr_add(ref Fr z, in Fr x, in Fr y); |
||||
[DllImport(dllName)] public static extern void mclBnFr_sub(ref Fr z, in Fr x, in Fr y); |
||||
[DllImport(dllName)] public static extern void mclBnFr_mul(ref Fr z, in Fr x, in Fr y); |
||||
[DllImport(dllName)] public static extern void mclBnFr_div(ref Fr z, in Fr x, in Fr y); |
||||
|
||||
[DllImport(dllName)] public static extern void mclBnFp_clear(ref Fp x); |
||||
[DllImport(dllName)] public static extern void mclBnFp_setInt(ref Fp y, int x); |
||||
[DllImport(dllName)] public static extern int mclBnFp_setStr(ref Fp x, [In][MarshalAs(UnmanagedType.LPStr)] string buf, long bufSize, int ioMode); |
||||
[DllImport(dllName)] public static extern int mclBnFp_isValid(in Fp x); |
||||
[DllImport(dllName)] public static extern int mclBnFp_isEqual(in Fp x, in Fp y); |
||||
[DllImport(dllName)] public static extern int mclBnFp_isZero(in Fp x); |
||||
[DllImport(dllName)] public static extern int mclBnFp_isOne(in Fp x); |
||||
[DllImport(dllName)] public static extern void mclBnFp_setByCSPRNG(ref Fp x); |
||||
|
||||
[DllImport(dllName)] public static extern int mclBnFp_setHashOf(ref Fp x, [In][MarshalAs(UnmanagedType.LPStr)] string buf, long bufSize); |
||||
[DllImport(dllName)] public static extern int mclBnFp_getStr([Out] StringBuilder buf, long maxBufSize, in Fp x, int ioMode); |
||||
|
||||
[DllImport(dllName)] public static extern void mclBnFp_neg(ref Fp y, in Fp x); |
||||
[DllImport(dllName)] public static extern void mclBnFp_inv(ref Fp y, in Fp x); |
||||
[DllImport(dllName)] public static extern void mclBnFp_add(ref Fp z, in Fp x, in Fp y); |
||||
[DllImport(dllName)] public static extern void mclBnFp_sub(ref Fp z, in Fp x, in Fp y); |
||||
[DllImport(dllName)] public static extern void mclBnFp_mul(ref Fp z, in Fp x, in Fp y); |
||||
[DllImport(dllName)] public static extern void mclBnFp_div(ref Fp z, in Fp x, in Fp y); |
||||
|
||||
[DllImport(dllName)] public static extern void mclBnG1_clear(ref G1 x); |
||||
[DllImport(dllName)] public static extern int mclBnG1_setStr(ref G1 x, [In][MarshalAs(UnmanagedType.LPStr)] string buf, long bufSize, int ioMode); |
||||
[DllImport(dllName)] public static extern int mclBnG1_isValid(in G1 x); |
||||
[DllImport(dllName)] public static extern int mclBnG1_isEqual(in G1 x, in G1 y); |
||||
[DllImport(dllName)] public static extern int mclBnG1_isZero(in G1 x); |
||||
[DllImport(dllName)] public static extern int mclBnG1_hashAndMapTo(ref G1 x, [In][MarshalAs(UnmanagedType.LPStr)] string buf, long bufSize); |
||||
[DllImport(dllName)] public static extern long mclBnG1_getStr([Out] StringBuilder buf, long maxBufSize, in G1 x, int ioMode); |
||||
[DllImport(dllName)] public static extern void mclBnG1_neg(ref G1 y, in G1 x); |
||||
[DllImport(dllName)] public static extern void mclBnG1_dbl(ref G1 y, in G1 x); |
||||
[DllImport(dllName)] public static extern void mclBnG1_normalize(ref G1 y, in G1 x); |
||||
[DllImport(dllName)] public static extern void mclBnG1_add(ref G1 z, in G1 x, in G1 y); |
||||
[DllImport(dllName)] public static extern void mclBnG1_sub(ref G1 z, in G1 x, in G1 y); |
||||
[DllImport(dllName)] public static extern void mclBnG1_mul(ref G1 z, in G1 x, in Fr y); |
||||
|
||||
[DllImport(dllName)] public static extern void mclBnG2_clear(ref G2 x); |
||||
[DllImport(dllName)] public static extern int mclBnG2_setStr(ref G2 x, [In][MarshalAs(UnmanagedType.LPStr)] string buf, long bufSize, int ioMode); |
||||
[DllImport(dllName)] public static extern int mclBnG2_isValid(in G2 x); |
||||
[DllImport(dllName)] public static extern int mclBnG2_isEqual(in G2 x, in G2 y); |
||||
[DllImport(dllName)] public static extern int mclBnG2_isZero(in G2 x); |
||||
[DllImport(dllName)] public static extern int mclBnG2_hashAndMapTo(ref G2 x, [In][MarshalAs(UnmanagedType.LPStr)] string buf, long bufSize); |
||||
[DllImport(dllName)] public static extern long mclBnG2_getStr([Out] StringBuilder buf, long maxBufSize, in G2 x, int ioMode); |
||||
[DllImport(dllName)] public static extern void mclBnG2_neg(ref G2 y, in G2 x); |
||||
[DllImport(dllName)] public static extern void mclBnG2_dbl(ref G2 y, in G2 x); |
||||
[DllImport(dllName)] public static extern void mclBnG2_normalize(ref G2 y, in G2 x); |
||||
[DllImport(dllName)] public static extern void mclBnG2_add(ref G2 z, in G2 x, in G2 y); |
||||
[DllImport(dllName)] public static extern void mclBnG2_sub(ref G2 z, in G2 x, in G2 y); |
||||
[DllImport(dllName)] public static extern void mclBnG2_mul(ref G2 z, in G2 x, in Fr y); |
||||
|
||||
[DllImport(dllName)] public static extern void mclBnGT_clear(ref GT x); |
||||
[DllImport(dllName)] public static extern int mclBnGT_setStr(ref GT x, [In][MarshalAs(UnmanagedType.LPStr)] string buf, long bufSize, int ioMode); |
||||
[DllImport(dllName)] public static extern int mclBnGT_isEqual(in GT x, in GT y); |
||||
[DllImport(dllName)] public static extern int mclBnGT_isZero(in GT x); |
||||
[DllImport(dllName)] public static extern int mclBnGT_isOne(in GT x); |
||||
[DllImport(dllName)] public static extern long mclBnGT_getStr([Out] StringBuilder buf, long maxBufSize, in GT x, int ioMode); |
||||
[DllImport(dllName)] public static extern void mclBnGT_neg(ref GT y, in GT x); |
||||
[DllImport(dllName)] public static extern void mclBnGT_inv(ref GT y, in GT x); |
||||
[DllImport(dllName)] public static extern void mclBnGT_add(ref GT z, in GT x, in GT y); |
||||
[DllImport(dllName)] public static extern void mclBnGT_sub(ref GT z, in GT x, in GT y); |
||||
[DllImport(dllName)] public static extern void mclBnGT_mul(ref GT z, in GT x, in GT y); |
||||
[DllImport(dllName)] public static extern void mclBnGT_div(ref GT z, in GT x, in GT y); |
||||
[DllImport(dllName)] public static extern void mclBnGT_pow(ref GT z, in GT x, in Fr y); |
||||
[DllImport(dllName)] public static extern void mclBn_pairing(ref GT z, in G1 x, in G2 y); |
||||
[DllImport(dllName)] public static extern void mclBn_finalExp(ref GT y, in GT x); |
||||
[DllImport(dllName)] public static extern void mclBn_millerLoop(ref GT z, in G1 x, in G2 y); |
||||
[DllImport(dllName)] public static extern ulong mclBnFp_setLittleEndianMod(ref Fp y, [In] byte[] buf, ulong bufSize); |
||||
[DllImport(dllName)] public static extern ulong mclBnFr_setLittleEndianMod(ref Fr y, [In] byte[] buf, ulong bufSize); |
||||
[DllImport(dllName)] public static extern ulong mclBnFp_setBigEndianMod(ref Fp y, [In] byte[] buf, ulong bufSize); |
||||
[DllImport(dllName)] public static extern ulong mclBnFr_setBigEndianMod(ref Fr y, [In] byte[] buf, ulong bufSize); |
||||
[DllImport(dllName)] public static extern int mclBn_getFrByteSize(); |
||||
[DllImport(dllName)] public static extern int mclBn_getFpByteSize(); |
||||
[DllImport(dllName)] public static extern ulong mclBnFp_serialize([Out] byte[] buf, ulong maxBufSize, in Fp x); |
||||
[DllImport(dllName)] public static extern ulong mclBnFr_serialize([Out] byte[] buf, ulong maxBufSize, in Fr x); |
||||
[DllImport(dllName)] public static extern ulong mclBnG1_serialize([Out]byte[] buf, ulong maxBufSize, in G1 x); |
||||
[DllImport(dllName)] public static extern ulong mclBnG2_serialize([Out]byte[] buf, ulong maxBufSize, in G2 x); |
||||
[DllImport(dllName)] public static extern ulong mclBnFr_deserialize(ref Fr x, [In]byte[] buf, ulong bufSize); |
||||
[DllImport(dllName)] public static extern ulong mclBnFp_deserialize(ref Fp x, [In]byte[] buf, ulong bufSize); |
||||
[DllImport(dllName)] public static extern ulong mclBnG1_deserialize(ref G1 x, [In]byte[] buf, ulong bufSize); |
||||
[DllImport(dllName)] public static extern ulong mclBnG2_deserialize(ref G2 x, [In]byte[] buf, ulong bufSize); |
||||
|
||||
public static void Init(int curveType = BN254) |
||||
{ |
||||
if (!System.Environment.Is64BitProcess) { |
||||
throw new PlatformNotSupportedException("not 64-bit system"); |
||||
} |
||||
const int COMPILED_TIME_VAR = FR_UNIT_SIZE * 10 + FP_UNIT_SIZE; |
||||
if (mclBn_init(curveType, COMPILED_TIME_VAR) != 0) { |
||||
throw new ArgumentException("mclBn_init"); |
||||
} |
||||
} |
||||
public static void ETHmode() |
||||
{ |
||||
mclBn_setETHserialization(1); |
||||
mclBn_setMapToMode(MCL_MAP_TO_MODE_HASH_TO_CURVE); |
||||
} |
||||
[StructLayout(LayoutKind.Sequential)] |
||||
struct U128 { |
||||
private ulong v0, v1; |
||||
} |
||||
|
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public struct Fr { |
||||
private U128 v0, v1; |
||||
public void Clear() |
||||
{ |
||||
mclBnFr_clear(ref this); |
||||
} |
||||
public void SetInt(int x) |
||||
{ |
||||
mclBnFr_setInt(ref this, x); |
||||
} |
||||
public void SetStr(string s, int ioMode) |
||||
{ |
||||
if (mclBnFr_setStr(ref this, s, s.Length, ioMode) != 0) { |
||||
throw new ArgumentException("mclBnFr_setStr" + s); |
||||
} |
||||
} |
||||
public bool IsValid() |
||||
{ |
||||
return mclBnFr_isValid(this) == 1; |
||||
} |
||||
public bool Equals(in Fr rhs) |
||||
{ |
||||
return mclBnFr_isEqual(this, rhs) == 1; |
||||
} |
||||
public bool IsZero() |
||||
{ |
||||
return mclBnFr_isZero(this) == 1; |
||||
} |
||||
public bool IsOne() |
||||
{ |
||||
return mclBnFr_isOne(this) == 1; |
||||
} |
||||
public void SetByCSPRNG() |
||||
{ |
||||
mclBnFr_setByCSPRNG(ref this); |
||||
} |
||||
public void SetHashOf(String s) |
||||
{ |
||||
if (mclBnFr_setHashOf(ref this, s, s.Length) != 0) { |
||||
throw new InvalidOperationException("mclBnFr_setHashOf:" + s); |
||||
} |
||||
} |
||||
public string GetStr(int ioMode) |
||||
{ |
||||
StringBuilder sb = new StringBuilder(1024); |
||||
long size = mclBnFr_getStr(sb, sb.Capacity, this, ioMode); |
||||
if (size == 0) { |
||||
throw new InvalidOperationException("mclBnFr_getStr:"); |
||||
} |
||||
return sb.ToString(); |
||||
} |
||||
public byte[] Serialize() |
||||
{ |
||||
byte[] buf = new byte[mclBn_getFrByteSize()]; |
||||
ulong n = mclBnFr_serialize(buf, (ulong)buf.Length, this); |
||||
if (n != (ulong)buf.Length) { |
||||
throw new ArithmeticException("mclBnFr_serialize"); |
||||
} |
||||
return buf; |
||||
} |
||||
public void Deserialize(byte[] buf) |
||||
{ |
||||
ulong n = mclBnFr_deserialize(ref this, buf, (ulong)buf.Length); |
||||
if (n == 0) { |
||||
throw new ArithmeticException("mclBnFr_deserialize"); |
||||
} |
||||
} |
||||
public void SetLittleEndianMod(byte[] buf) |
||||
{ |
||||
ulong n = mclBnFr_setLittleEndianMod(ref this, buf, (ulong)buf.Length); |
||||
if (n == 0) { |
||||
throw new ArithmeticException("mclBnFr_setLittleEndianMod"); |
||||
} |
||||
} |
||||
public void SetBigEndianMod(byte[] buf) |
||||
{ |
||||
ulong n = mclBnFr_setBigEndianMod(ref this, buf, (ulong)buf.Length); |
||||
if (n == 0) { |
||||
throw new ArithmeticException("mclBnFr_setBigEndianMod"); |
||||
} |
||||
} |
||||
|
||||
public void Neg(in Fr x) |
||||
{ |
||||
mclBnFr_neg(ref this, x); |
||||
} |
||||
public void Inv(in Fr x) |
||||
{ |
||||
mclBnFr_inv(ref this, x); |
||||
} |
||||
public void Add(in Fr x, in Fr y) |
||||
{ |
||||
mclBnFr_add(ref this, x, y); |
||||
} |
||||
public void Sub(in Fr x, in Fr y) |
||||
{ |
||||
mclBnFr_sub(ref this, x, y); |
||||
} |
||||
public void Mul(in Fr x, in Fr y) |
||||
{ |
||||
mclBnFr_mul(ref this, x, y); |
||||
} |
||||
public void Div(in Fr x, in Fr y) |
||||
{ |
||||
mclBnFr_div(ref this, x, y); |
||||
} |
||||
public static Fr operator -(in Fr x) |
||||
{ |
||||
Fr y = new Fr(); |
||||
y.Neg(x); |
||||
return y; |
||||
} |
||||
public static Fr operator +(in Fr x, in Fr y) |
||||
{ |
||||
Fr z = new Fr(); |
||||
z.Add(x, y); |
||||
return z; |
||||
} |
||||
public static Fr operator -(in Fr x, in Fr y) |
||||
{ |
||||
Fr z = new Fr(); |
||||
z.Sub(x, y); |
||||
return z; |
||||
} |
||||
public static Fr operator *(in Fr x, in Fr y) |
||||
{ |
||||
Fr z = new Fr(); |
||||
z.Mul(x, y); |
||||
return z; |
||||
} |
||||
public static Fr operator /(in Fr x, in Fr y) |
||||
{ |
||||
Fr z = new Fr(); |
||||
z.Div(x, y); |
||||
return z; |
||||
} |
||||
} |
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public struct Fp { |
||||
private U128 v0, v1, v2; |
||||
public void Clear() |
||||
{ |
||||
mclBnFp_clear(ref this); |
||||
} |
||||
public void SetInt(int x) |
||||
{ |
||||
mclBnFp_setInt(ref this, x); |
||||
} |
||||
public void SetStr(string s, int ioMode) |
||||
{ |
||||
if (mclBnFp_setStr(ref this, s, s.Length, ioMode) != 0) { |
||||
throw new ArgumentException("mclBnFp_setStr" + s); |
||||
} |
||||
} |
||||
public bool IsValid() |
||||
{ |
||||
return mclBnFp_isValid(this) == 1; |
||||
} |
||||
public bool Equals(in Fp rhs) |
||||
{ |
||||
return mclBnFp_isEqual(this, rhs) == 1; |
||||
} |
||||
public bool IsZero() |
||||
{ |
||||
return mclBnFp_isZero(this) == 1; |
||||
} |
||||
public bool IsOne() |
||||
{ |
||||
return mclBnFp_isOne(this) == 1; |
||||
} |
||||
public void SetByCSPRNG() |
||||
{ |
||||
mclBnFp_setByCSPRNG(ref this); |
||||
} |
||||
public string GetStr(int ioMode) |
||||
{ |
||||
StringBuilder sb = new StringBuilder(1024); |
||||
long size = mclBnFp_getStr(sb, sb.Capacity, this, ioMode); |
||||
if (size == 0) { |
||||
throw new InvalidOperationException("mclBnFp_getStr:"); |
||||
} |
||||
return sb.ToString(); |
||||
} |
||||
public byte[] Serialize() |
||||
{ |
||||
byte[] buf = new byte[mclBn_getFpByteSize()]; |
||||
ulong n = mclBnFp_serialize(buf, (ulong)buf.Length, this); |
||||
if (n != (ulong)buf.Length) { |
||||
throw new ArithmeticException("mclBnFp_serialize"); |
||||
} |
||||
return buf; |
||||
} |
||||
public void Deserialize(byte[] buf) |
||||
{ |
||||
ulong n = mclBnFp_deserialize(ref this, buf, (ulong)buf.Length); |
||||
if (n == 0) { |
||||
throw new ArithmeticException("mclBnFp_deserialize"); |
||||
} |
||||
} |
||||
public void SetLittleEndianMod(byte[] buf) |
||||
{ |
||||
ulong n = mclBnFp_setLittleEndianMod(ref this, buf, (ulong)buf.Length); |
||||
if (n == 0) { |
||||
throw new ArithmeticException("mclBnFp_setLittleEndianMod"); |
||||
} |
||||
} |
||||
public void SetBigEndianMod(byte[] buf) |
||||
{ |
||||
ulong n = mclBnFp_setBigEndianMod(ref this, buf, (ulong)buf.Length); |
||||
if (n == 0) { |
||||
throw new ArithmeticException("mclBnFp_setBigEndianMod"); |
||||
} |
||||
} |
||||
public void Neg(in Fp x) |
||||
{ |
||||
mclBnFp_neg(ref this, x); |
||||
} |
||||
public void Inv(in Fp x) |
||||
{ |
||||
mclBnFp_inv(ref this, x); |
||||
} |
||||
public void Add(in Fp x, in Fp y) |
||||
{ |
||||
mclBnFp_add(ref this, x, y); |
||||
} |
||||
public void Sub(in Fp x, in Fp y) |
||||
{ |
||||
mclBnFp_sub(ref this, x, y); |
||||
} |
||||
public void Mul(in Fp x, in Fp y) |
||||
{ |
||||
mclBnFp_mul(ref this, x, y); |
||||
} |
||||
public void Div(in Fp x, in Fp y) |
||||
{ |
||||
mclBnFp_div(ref this, x, y); |
||||
} |
||||
public static Fp operator -(in Fp x) |
||||
{ |
||||
Fp y = new Fp(); |
||||
y.Neg(x); |
||||
return y; |
||||
} |
||||
public static Fp operator +(in Fp x, in Fp y) |
||||
{ |
||||
Fp z = new Fp(); |
||||
z.Add(x, y); |
||||
return z; |
||||
} |
||||
public static Fp operator -(in Fp x, in Fp y) |
||||
{ |
||||
Fp z = new Fp(); |
||||
z.Sub(x, y); |
||||
return z; |
||||
} |
||||
public static Fp operator *(in Fp x, in Fp y) |
||||
{ |
||||
Fp z = new Fp(); |
||||
z.Mul(x, y); |
||||
return z; |
||||
} |
||||
public static Fp operator /(in Fp x, in Fp y) |
||||
{ |
||||
Fp z = new Fp(); |
||||
z.Div(x, y); |
||||
return z; |
||||
} |
||||
} |
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public struct Fp2 { |
||||
private Fp a, b; |
||||
} |
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public struct G1 { |
||||
private Fp x, y, z; |
||||
public void Clear() |
||||
{ |
||||
mclBnG1_clear(ref this); |
||||
} |
||||
public void SetStr(String s, int ioMode) |
||||
{ |
||||
if (mclBnG1_setStr(ref this, s, s.Length, ioMode) != 0) { |
||||
throw new ArgumentException("mclBnG1_setStr:" + s); |
||||
} |
||||
} |
||||
public bool IsValid() |
||||
{ |
||||
return mclBnG1_isValid(this) == 1; |
||||
} |
||||
public bool Equals(in G1 rhs) |
||||
{ |
||||
return mclBnG1_isEqual(this, rhs) == 1; |
||||
} |
||||
public bool IsZero() |
||||
{ |
||||
return mclBnG1_isZero(this) == 1; |
||||
} |
||||
public void HashAndMapTo(String s) |
||||
{ |
||||
if (mclBnG1_hashAndMapTo(ref this, s, s.Length) != 0) { |
||||
throw new ArgumentException("mclBnG1_hashAndMapTo:" + s); |
||||
} |
||||
} |
||||
public string GetStr(int ioMode) |
||||
{ |
||||
StringBuilder sb = new StringBuilder(1024); |
||||
long size = mclBnG1_getStr(sb, sb.Capacity, this, ioMode); |
||||
if (size == 0) { |
||||
throw new InvalidOperationException("mclBnG1_getStr:"); |
||||
} |
||||
return sb.ToString(); |
||||
} |
||||
public byte[] Serialize() |
||||
{ |
||||
byte[] buf = new byte[mclBn_getFpByteSize()]; |
||||
ulong n = mclBnG1_serialize(buf, (ulong)buf.Length, this); |
||||
if (n != (ulong)buf.Length) { |
||||
throw new ArithmeticException("mclBnG1_serialize"); |
||||
} |
||||
return buf; |
||||
} |
||||
public void Deserialize(byte[] buf) |
||||
{ |
||||
ulong n = mclBnG1_deserialize(ref this, buf, (ulong)buf.Length); |
||||
if (n == 0) { |
||||
throw new ArithmeticException("mclBnG1_deserialize"); |
||||
} |
||||
} |
||||
public void Neg(in G1 x) |
||||
{ |
||||
mclBnG1_neg(ref this, x); |
||||
} |
||||
public void Dbl(in G1 x) |
||||
{ |
||||
mclBnG1_dbl(ref this, x); |
||||
} |
||||
public void Normalize(in G1 x) |
||||
{ |
||||
mclBnG1_normalize(ref this, x); |
||||
} |
||||
public void Add(in G1 x, in G1 y) |
||||
{ |
||||
mclBnG1_add(ref this, x, y); |
||||
} |
||||
public void Sub(in G1 x, in G1 y) |
||||
{ |
||||
mclBnG1_sub(ref this, x, y); |
||||
} |
||||
public void Mul(in G1 x, in Fr y) |
||||
{ |
||||
mclBnG1_mul(ref this, x, y); |
||||
} |
||||
} |
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public struct G2 { |
||||
private Fp2 x, y, z; |
||||
public void Clear() |
||||
{ |
||||
mclBnG2_clear(ref this); |
||||
} |
||||
public void SetStr(String s, int ioMode) |
||||
{ |
||||
if (mclBnG2_setStr(ref this, s, s.Length, ioMode) != 0) { |
||||
throw new ArgumentException("mclBnG2_setStr:" + s); |
||||
} |
||||
} |
||||
public bool IsValid() |
||||
{ |
||||
return mclBnG2_isValid(this) == 1; |
||||
} |
||||
public bool Equals(in G2 rhs) |
||||
{ |
||||
return mclBnG2_isEqual(this, rhs) == 1; |
||||
} |
||||
public bool IsZero() |
||||
{ |
||||
return mclBnG2_isZero(this) == 1; |
||||
} |
||||
public void HashAndMapTo(String s) |
||||
{ |
||||
if (mclBnG2_hashAndMapTo(ref this, s, s.Length) != 0) { |
||||
throw new ArgumentException("mclBnG2_hashAndMapTo:" + s); |
||||
} |
||||
} |
||||
public string GetStr(int ioMode) |
||||
{ |
||||
StringBuilder sb = new StringBuilder(1024); |
||||
long size = mclBnG2_getStr(sb, sb.Capacity, this, ioMode); |
||||
if (size == 0) { |
||||
throw new InvalidOperationException("mclBnG2_getStr:"); |
||||
} |
||||
return sb.ToString(); |
||||
} |
||||
public byte[] Serialize() |
||||
{ |
||||
byte[] buf = new byte[mclBn_getFpByteSize() * 2]; |
||||
ulong n = mclBnG2_serialize(buf, (ulong)buf.Length, this); |
||||
if (n != (ulong)buf.Length) { |
||||
throw new ArithmeticException("mclBnG2_serialize"); |
||||
} |
||||
return buf; |
||||
} |
||||
public void Deserialize(byte[] buf) |
||||
{ |
||||
ulong n = mclBnG2_deserialize(ref this, buf, (ulong)buf.Length); |
||||
if (n == 0) { |
||||
throw new ArithmeticException("mclBnG2_deserialize"); |
||||
} |
||||
} |
||||
public void Neg(in G2 x) |
||||
{ |
||||
mclBnG2_neg(ref this, x); |
||||
} |
||||
public void Dbl(in G2 x) |
||||
{ |
||||
mclBnG2_dbl(ref this, x); |
||||
} |
||||
public void Normalize(in G2 x) |
||||
{ |
||||
mclBnG2_normalize(ref this, x); |
||||
} |
||||
public void Add(in G2 x, in G2 y) |
||||
{ |
||||
mclBnG2_add(ref this, x, y); |
||||
} |
||||
public void Sub(in G2 x, in G2 y) |
||||
{ |
||||
mclBnG2_sub(ref this, x, y); |
||||
} |
||||
public void Mul(in G2 x, Fr y) |
||||
{ |
||||
mclBnG2_mul(ref this, x, y); |
||||
} |
||||
} |
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public struct GT { |
||||
private Fp v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11; |
||||
public void Clear() |
||||
{ |
||||
mclBnGT_clear(ref this); |
||||
} |
||||
public void SetStr(String s, int ioMode) |
||||
{ |
||||
if (mclBnGT_setStr(ref this, s, s.Length, ioMode) != 0) { |
||||
throw new ArgumentException("mclBnGT_setStr:" + s); |
||||
} |
||||
} |
||||
public bool Equals(in GT rhs) |
||||
{ |
||||
return mclBnGT_isEqual(this, rhs) == 1; |
||||
} |
||||
public bool IsZero() |
||||
{ |
||||
return mclBnGT_isZero(this) == 1; |
||||
} |
||||
public bool IsOne() |
||||
{ |
||||
return mclBnGT_isOne(this) == 1; |
||||
} |
||||
public string GetStr(int ioMode) |
||||
{ |
||||
StringBuilder sb = new StringBuilder(1024); |
||||
long size = mclBnGT_getStr(sb, sb.Capacity, this, ioMode); |
||||
if (size == 0) { |
||||
throw new InvalidOperationException("mclBnGT_getStr:"); |
||||
} |
||||
return sb.ToString(); |
||||
} |
||||
public void Neg(in GT x) |
||||
{ |
||||
mclBnGT_neg(ref this, x); |
||||
} |
||||
public void Inv(in GT x) |
||||
{ |
||||
mclBnGT_inv(ref this, x); |
||||
} |
||||
public void Add(in GT x, in GT y) |
||||
{ |
||||
mclBnGT_add(ref this, x, y); |
||||
} |
||||
public void Sub(in GT x, in GT y) |
||||
{ |
||||
mclBnGT_sub(ref this, x, y); |
||||
} |
||||
public void Mul(in GT x, in GT y) |
||||
{ |
||||
mclBnGT_mul(ref this, x, y); |
||||
} |
||||
public void Div(in GT x, in GT y) |
||||
{ |
||||
mclBnGT_div(ref this, x, y); |
||||
} |
||||
public static GT operator -(in GT x) |
||||
{ |
||||
GT y = new GT(); |
||||
y.Neg(x); |
||||
return y; |
||||
} |
||||
public static GT operator +(in GT x, in GT y) |
||||
{ |
||||
GT z = new GT(); |
||||
z.Add(x, y); |
||||
return z; |
||||
} |
||||
public static GT operator -(in GT x, in GT y) |
||||
{ |
||||
GT z = new GT(); |
||||
z.Sub(x, y); |
||||
return z; |
||||
} |
||||
public static GT operator *(in GT x, in GT y) |
||||
{ |
||||
GT z = new GT(); |
||||
z.Mul(x, y); |
||||
return z; |
||||
} |
||||
public static GT operator /(in GT x, in GT y) |
||||
{ |
||||
GT z = new GT(); |
||||
z.Div(x, y); |
||||
return z; |
||||
} |
||||
public void Pow(in GT x, in Fr y) |
||||
{ |
||||
mclBnGT_pow(ref this, x, y); |
||||
} |
||||
public void Pairing(in G1 x, in G2 y) |
||||
{ |
||||
mclBn_pairing(ref this, x, y); |
||||
} |
||||
public void FinalExp(in GT x) |
||||
{ |
||||
mclBn_finalExp(ref this, x); |
||||
} |
||||
public void MillerLoop(in G1 x, in G2 y) |
||||
{ |
||||
mclBn_millerLoop(ref this, x, y); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,13 @@ |
||||
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
||||
<PropertyGroup> |
||||
<TargetFramework>netstandard2.1</TargetFramework> |
||||
</PropertyGroup> |
||||
|
||||
<ItemGroup> |
||||
<Compile Remove="CVS\**" /> |
||||
<EmbeddedResource Remove="CVS\**" /> |
||||
<None Remove="CVS\**" /> |
||||
</ItemGroup> |
||||
|
||||
</Project> |
@ -0,0 +1,11 @@ |
||||
# C# binding of mcl library |
||||
|
||||
# How to build `bin/mclbn384_256.dll`. |
||||
|
||||
``` |
||||
git clone https://github.com/herumi/mcl |
||||
cd mcl |
||||
mklib dll |
||||
``` |
||||
|
||||
Open `ffi/cs/mcl.sln` and Set the directory of `mcl/bin` to `workingDirectory` at `Debug` of test project. |
@ -0,0 +1,224 @@ |
||||
using System; |
||||
|
||||
namespace mcl { |
||||
using static MCL; |
||||
class MCLTest { |
||||
static int err = 0; |
||||
static void assert(string msg, bool b) |
||||
{ |
||||
if (b) return; |
||||
Console.WriteLine("ERR {0}", msg); |
||||
err++; |
||||
} |
||||
static void Main(string[] args) |
||||
{ |
||||
err = 0; |
||||
try { |
||||
Console.WriteLine("BN254"); |
||||
TestCurve(BN254); |
||||
Console.WriteLine("BN_SNARK"); |
||||
TestCurve(BN_SNARK); |
||||
Console.WriteLine("BLS12_381"); |
||||
TestCurve(BLS12_381); |
||||
if (err == 0) { |
||||
Console.WriteLine("all tests succeed"); |
||||
} else { |
||||
Console.WriteLine("err={0}", err); |
||||
} |
||||
} catch (Exception e) { |
||||
Console.WriteLine("ERR={0}", e); |
||||
} |
||||
} |
||||
|
||||
static void TestCurve(int curveType) |
||||
|
||||
{ |
||||
Init(curveType); |
||||
TestFr(); |
||||
TestFp(); |
||||
TestG1(); |
||||
TestG2(); |
||||
TestPairing(); |
||||
} |
||||
static void TestFr() |
||||
{ |
||||
Console.WriteLine("TestFr"); |
||||
Fr x = new Fr(); |
||||
x.Clear(); |
||||
assert("0", x.GetStr(10) == "0"); |
||||
assert("0.IzZero", x.IsZero()); |
||||
assert("!0.IzOne", !x.IsOne()); |
||||
x.SetInt(1); |
||||
assert("1", x.GetStr(10) == "1"); |
||||
assert("!1.IzZero", !x.IsZero()); |
||||
assert("1.IzOne", x.IsOne()); |
||||
x.SetInt(3); |
||||
assert("3", x.GetStr(10) == "3"); |
||||
assert("!3.IzZero", !x.IsZero()); |
||||
assert("!3.IzOne", !x.IsOne()); |
||||
x.SetInt(-5); |
||||
x = -x; |
||||
assert("5", x.GetStr(10) == "5"); |
||||
x.SetInt(4); |
||||
x = x * x; |
||||
assert("16", x.GetStr(10) == "16"); |
||||
assert("10", x.GetStr(16) == "10"); |
||||
Fr y; |
||||
y = x; |
||||
assert("x == y", x.Equals(y)); |
||||
x.SetInt(123); |
||||
assert("123", x.GetStr(10) == "123"); |
||||
assert("7b", x.GetStr(16) == "7b"); |
||||
assert("y != x", !x.Equals(y)); |
||||
Console.WriteLine("exception test"); |
||||
try { |
||||
x.SetStr("1234567891234x", 10); |
||||
Console.WriteLine("x = {0}", x); |
||||
} catch (Exception e) { |
||||
Console.WriteLine("OK ; expected exception: {0}", e); |
||||
} |
||||
x.SetStr("1234567891234", 10); |
||||
assert("1234567891234", x.GetStr(10) == "1234567891234"); |
||||
{ |
||||
byte[] buf = x.Serialize(); |
||||
y.Deserialize(buf); |
||||
assert("x == y", x.Equals(y)); |
||||
} |
||||
} |
||||
static void TestFp() |
||||
{ |
||||
Console.WriteLine("TestFp"); |
||||
Fp x = new Fp(); |
||||
x.Clear(); |
||||
assert("0", x.GetStr(10) == "0"); |
||||
assert("0.IzZero", x.IsZero()); |
||||
assert("!0.IzOne", !x.IsOne()); |
||||
x.SetInt(1); |
||||
assert("1", x.GetStr(10) == "1"); |
||||
assert("!1.IzZero", !x.IsZero()); |
||||
assert("1.IzOne", x.IsOne()); |
||||
x.SetInt(3); |
||||
assert("3", x.GetStr(10) == "3"); |
||||
assert("!3.IzZero", !x.IsZero()); |
||||
assert("!3.IzOne", !x.IsOne()); |
||||
x.SetInt(-5); |
||||
x = -x; |
||||
assert("5", x.GetStr(10) == "5"); |
||||
x.SetInt(4); |
||||
x = x * x; |
||||
assert("16", x.GetStr(10) == "16"); |
||||
assert("10", x.GetStr(16) == "10"); |
||||
Fp y; |
||||
y = x; |
||||
assert("x == y", x.Equals(y)); |
||||
x.SetInt(123); |
||||
assert("123", x.GetStr(10) == "123"); |
||||
assert("7b", x.GetStr(16) == "7b"); |
||||
assert("y != x", !x.Equals(y)); |
||||
Console.WriteLine("exception test"); |
||||
try { |
||||
x.SetStr("1234567891234x", 10); |
||||
Console.WriteLine("x = {0}", x); |
||||
} catch (Exception e) { |
||||
Console.WriteLine("OK ; expected exception: {0}", e); |
||||
} |
||||
x.SetStr("1234567891234", 10); |
||||
assert("1234567891234", x.GetStr(10) == "1234567891234"); |
||||
{ |
||||
byte[] buf = x.Serialize(); |
||||
y.Deserialize(buf); |
||||
assert("x == y", x.Equals(y)); |
||||
} |
||||
} |
||||
static void TestG1() |
||||
{ |
||||
Console.WriteLine("TestG1"); |
||||
G1 P = new G1(); |
||||
P.Clear(); |
||||
assert("P.IsValid", P.IsValid()); |
||||
assert("P.IsZero", P.IsZero()); |
||||
P.HashAndMapTo("abc"); |
||||
assert("P.IsValid", P.IsValid()); |
||||
assert("!P.IsZero", !P.IsZero()); |
||||
G1 Q = new G1(); |
||||
Q = P; |
||||
assert("P == Q", Q.Equals(P)); |
||||
Q.Neg(P); |
||||
Q.Add(Q, P); |
||||
assert("P = Q", Q.IsZero()); |
||||
Q.Dbl(P); |
||||
G1 R = new G1(); |
||||
R.Add(P, P); |
||||
assert("Q == R", Q.Equals(R)); |
||||
Fr x = new Fr(); |
||||
x.SetInt(3); |
||||
R.Add(R, P); |
||||
Q.Mul(P, x); |
||||
assert("Q == R", Q.Equals(R)); |
||||
{ |
||||
byte[] buf = P.Serialize(); |
||||
Q.Clear(); |
||||
Q.Deserialize(buf); |
||||
assert("P == Q", P.Equals(Q)); |
||||
} |
||||
} |
||||
static void TestG2() |
||||
{ |
||||
Console.WriteLine("TestG2"); |
||||
G2 P = new G2(); |
||||
P.Clear(); |
||||
assert("P is valid", P.IsValid()); |
||||
assert("P is zero", P.IsZero()); |
||||
P.HashAndMapTo("abc"); |
||||
assert("P is valid", P.IsValid()); |
||||
assert("P is not zero", !P.IsZero()); |
||||
G2 Q = new G2(); |
||||
Q = P; |
||||
assert("P == Q", Q.Equals(P)); |
||||
Q.Neg(P); |
||||
Q.Add(Q, P); |
||||
assert("Q is zero", Q.IsZero()); |
||||
Q.Dbl(P); |
||||
G2 R = new G2(); |
||||
R.Add(P, P); |
||||
assert("Q == R", Q.Equals(R)); |
||||
Fr x = new Fr(); |
||||
x.SetInt(3); |
||||
R.Add(R, P); |
||||
Q.Mul(P, x); |
||||
assert("Q == R", Q.Equals(R)); |
||||
{ |
||||
byte[] buf = P.Serialize(); |
||||
Q.Clear(); |
||||
Q.Deserialize(buf); |
||||
assert("P == Q", P.Equals(Q)); |
||||
} |
||||
} |
||||
static void TestPairing() |
||||
{ |
||||
Console.WriteLine("TestG2"); |
||||
G1 P = new G1(); |
||||
P.HashAndMapTo("123"); |
||||
G2 Q = new G2(); |
||||
Q.HashAndMapTo("1"); |
||||
Fr a = new Fr(); |
||||
Fr b = new Fr(); |
||||
a.SetStr("12345678912345673453", 10); |
||||
b.SetStr("230498230982394243424", 10); |
||||
G1 aP = new G1(); |
||||
G2 bQ = new G2(); |
||||
aP.Mul(P, a); |
||||
bQ.Mul(Q, b); |
||||
GT e1 = new GT(); |
||||
GT e2 = new GT(); |
||||
GT e3 = new GT(); |
||||
e1.Pairing(P, Q); |
||||
e2.Pairing(aP, Q); |
||||
e3.Pow(e1, a); |
||||
assert("e2.Equals(e3)", e2.Equals(e3)); |
||||
e2.Pairing(P, bQ); |
||||
e3.Pow(e1, b); |
||||
assert("e2.Equals(e3)", e2.Equals(e3)); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,28 @@ |
||||
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
||||
<ItemGroup> |
||||
<Compile Remove="CVS\**" /> |
||||
<EmbeddedResource Remove="CVS\**" /> |
||||
<None Remove="CVS\**" /> |
||||
</ItemGroup> |
||||
|
||||
<ItemGroup> |
||||
<ProjectReference Include="..\mcl\mcl.csproj" /> |
||||
</ItemGroup> |
||||
|
||||
<PropertyGroup> |
||||
<OutputType>Exe</OutputType> |
||||
<TargetFramework>netcoreapp3.1</TargetFramework> |
||||
</PropertyGroup> |
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> |
||||
<PlatformTarget>x64</PlatformTarget> |
||||
<OutputPath></OutputPath> |
||||
</PropertyGroup> |
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> |
||||
<PlatformTarget>x64</PlatformTarget> |
||||
<OutputPath></OutputPath> |
||||
</PropertyGroup> |
||||
|
||||
</Project> |
@ -1,2 +1,2 @@ |
||||
set CFLAGS=/MT /DNOMINMAX /Ox /DNDEBUG /openmp /W4 /Zi /EHsc /nologo -I./include -I../cybozulib_ext/include |
||||
set LDFLAGS=/LIBPATH:..\cybozulib_ext\lib /LIBPATH:.\lib |
||||
set CFLAGS=/MT /DNOMINMAX /Ox /DNDEBUG /openmp /W4 /Zi /EHsc /nologo -I./include -I../cybozulib_ext/include -DMCL_DONT_USE_OPENSSL -DMCL_USE_VINT -DMCL_SIZEOF_UNIT=8 -DMCL_VINT_FIXED_BUFFER -DMCL_MAX_BIT_SIZE=384 |
||||
set LDFLAGS=/LIBPATH:.\lib |
||||
|
Loading…
Reference in new issue