diff --git a/ffi/cs/mcl/mcl.cs b/ffi/cs/mcl/mcl.cs index 0202a66..cf04071 100644 --- a/ffi/cs/mcl/mcl.cs +++ b/ffi/cs/mcl/mcl.cs @@ -19,7 +19,6 @@ namespace mcl { [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 int mclBn_FrEvaluatePolynomial(ref Fr z, [In] Fr[] poly, long bufSize, in Fr y); [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); @@ -73,7 +72,7 @@ namespace mcl { [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 mclBnG1_mulVec(ref G1 z, [In]G1[] x, [In]Fr[] y, long n); + [DllImport(dllName)] public static extern void mclBnG1_mulVec(ref G1 z, [In] G1[] x, [In] Fr[] y, long n); [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); @@ -115,13 +114,19 @@ namespace mcl { [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); + [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); + [DllImport(dllName)] public static extern int mclBn_FrEvaluatePolynomial(ref Fr z, [In] Fr[] cVec, ulong cSize, in Fr x); + [DllImport(dllName)] public static extern int mclBn_G1EvaluatePolynomial(ref G1 z, [In] G1[] cVec, ulong cSize, in Fr x); + [DllImport(dllName)] public static extern int mclBn_G2EvaluatePolynomial(ref G2 z, [In] G2[] cVec, ulong cSize, in Fr x); + [DllImport(dllName)] public static extern int mclBn_FrLagrangeInterpolation(ref Fr z, [In] Fr[] xVec, [In] Fr[] yVec, ulong k); + [DllImport(dllName)] public static extern int mclBn_G1LagrangeInterpolation(ref G1 z, [In] Fr[] xVec, [In] G1[] yVec, ulong k); + [DllImport(dllName)] public static extern int mclBn_G2LagrangeInterpolation(ref G2 z, [In] Fr[] xVec, [In] G2[] yVec, ulong k); public static void Init(int curveType = BN254) { if (!System.Environment.Is64BitProcess) { @@ -302,6 +307,65 @@ namespace mcl { { mclBn_millerLoop(ref z, x, y); } + // y = f(x) with a polynomial f(t) = sum_i cVec[i] t^i + public static void Share(ref Fr y, in Fr[] cVec, in Fr x) + { + ulong k = (ulong)cVec.Length; + int ret = mclBn_FrEvaluatePolynomial(ref y, cVec, k, x); + if (ret != 0) { + throw new ArgumentException("mclBn_FrEvaluatePolynomial"); + } + } + public static void Share(ref G1 y, in G1[] cVec, in Fr x) + { + ulong k = (ulong)cVec.Length; + int ret = mclBn_G1EvaluatePolynomial(ref y, cVec, k, x); + if (ret != 0) { + throw new ArgumentException("mclBn_G1EvaluatePolynomial"); + } + } + public static void Share(ref G2 y, in G2[] cVec, in Fr x) + { + ulong k = (ulong)cVec.Length; + int ret = mclBn_G2EvaluatePolynomial(ref y, cVec, k, x); + if (ret != 0) { + throw new ArgumentException("mclBn_G2EvaluatePolynomial"); + } + } + // recover z by Lagrange interpolation with {xVec[i], yVec[i]} + public static void Recover(ref Fr z, in Fr[] xVec, in Fr[] yVec) + { + if (xVec.Length != yVec.Length) { + throw new ArgumentException("bad length"); + } + ulong k = (ulong)xVec.Length; + int ret = mclBn_FrLagrangeInterpolation(ref z, xVec, yVec, k); + if (ret != 0) { + throw new ArgumentException("mclBn_FrLagrangeInterpolation:" + ret.ToString()); + } + } + public static void Recover(ref G1 z, in Fr[] xVec, in G1[] yVec) + { + if (xVec.Length != yVec.Length) { + throw new ArgumentException("bad length"); + } + ulong k = (ulong)xVec.Length; + int ret = mclBn_G1LagrangeInterpolation(ref z, xVec, yVec, k); + if (ret != 0) { + throw new ArgumentException("mclBn_G1LagrangeInterpolation:" + ret.ToString()); + } + } + public static void Recover(ref G2 z, in Fr[] xVec, in G2[] yVec) + { + if (xVec.Length != yVec.Length) { + throw new ArgumentException("bad length"); + } + ulong k = (ulong)xVec.Length; + int ret = mclBn_G2LagrangeInterpolation(ref z, xVec, yVec, k); + if (ret != 0) { + throw new ArgumentException("mclBn_G2LagrangeInterpolation:" + ret.ToString()); + } + } [StructLayout(LayoutKind.Sequential)] struct U128 { private ulong v0, v1; @@ -638,6 +702,10 @@ namespace mcl { throw new ArgumentException("mclBnG1_hashAndMapTo:" + s); } } + public void SetHashOf(String s) + { + HashAndMapTo(s); + } public string GetStr(int ioMode) { StringBuilder sb = new StringBuilder(1024); @@ -748,6 +816,10 @@ namespace mcl { throw new ArgumentException("mclBnG2_hashAndMapTo:" + s); } } + public void SetHashOf(String s) + { + HashAndMapTo(s); + } public string GetStr(int ioMode) { StringBuilder sb = new StringBuilder(1024); diff --git a/ffi/cs/test/test.cs b/ffi/cs/test/test.cs index d3c023b..b41aab4 100644 --- a/ffi/cs/test/test.cs +++ b/ffi/cs/test/test.cs @@ -10,7 +10,7 @@ namespace mcl { Console.WriteLine("ERR {0}", msg); err++; } - static void Main(string[] args) + static void Main() { err = 0; try { @@ -34,7 +34,6 @@ namespace mcl { } static void TestCurve(int curveType) - { Init(curveType); TestFr(); @@ -42,6 +41,7 @@ namespace mcl { TestG1(); TestG2(); TestPairing(); + TestSS(); } static void TestFr() { @@ -286,5 +286,123 @@ namespace mcl { { TestETH_mapToG1(); } + static void TestSS_Fr() + { + const int n = 5; + const int k = 3; // can't change because the following loop + Fr[] cVec = new Fr[k]; + // init polynomial coefficient + for (int i = 0; i < k; i++) { + cVec[i].SetByCSPRNG(); + } + + Fr[] xVec = new Fr[n]; + Fr[] yVec = new Fr[n]; + // share cVec[0] with yVec[0], ..., yVec[n-1] + for (int i = 0; i < n; i++) { + xVec[i].SetHashOf(i.ToString()); + MCL.Share(ref yVec[i], cVec, xVec[i]); + } + // recover cVec[0] from xVecSubset and yVecSubset + Fr[] xVecSubset = new Fr[k]; + Fr[] yVecSubset = new Fr[k]; + for (int i0 = 0; i0 < n; i0++) { + xVecSubset[0] = xVec[i0]; + yVecSubset[0] = yVec[i0]; + for (int i1 = i0 + 1; i1 < n; i1++) { + xVecSubset[1] = xVec[i1]; + yVecSubset[1] = yVec[i1]; + for (int i2 = i1 + 1; i2 < n; i2++) { + xVecSubset[2] = xVec[i2]; + yVecSubset[2] = yVec[i2]; + Fr s = new Fr(); + MCL.Recover(ref s, xVecSubset, yVecSubset); + assert("Recover", s.Equals(cVec[0])); + } + } + } + } + static void TestSS_G1() + { + const int n = 5; + const int k = 3; // can't change because the following loop + G1[] cVec = new G1[k]; + // init polynomial coefficient + for (int i = 0; i < k; i++) { + Fr x = new Fr(); + x.SetByCSPRNG(); + cVec[i].SetHashOf(x.GetStr(16)); + } + + Fr[] xVec = new Fr[n]; + G1[] yVec = new G1[n]; + // share cVec[0] with yVec[0], ..., yVec[n-1] + for (int i = 0; i < n; i++) { + xVec[i].SetHashOf(i.ToString()); + MCL.Share(ref yVec[i], cVec, xVec[i]); + } + // recover cVec[0] from xVecSubset and yVecSubset + Fr[] xVecSubset = new Fr[k]; + G1[] yVecSubset = new G1[k]; + for (int i0 = 0; i0 < n; i0++) { + xVecSubset[0] = xVec[i0]; + yVecSubset[0] = yVec[i0]; + for (int i1 = i0 + 1; i1 < n; i1++) { + xVecSubset[1] = xVec[i1]; + yVecSubset[1] = yVec[i1]; + for (int i2 = i1 + 1; i2 < n; i2++) { + xVecSubset[2] = xVec[i2]; + yVecSubset[2] = yVec[i2]; + G1 s = new G1(); + MCL.Recover(ref s, xVecSubset, yVecSubset); + assert("Recover", s.Equals(cVec[0])); + } + } + } + } + static void TestSS_G2() + { + const int n = 5; + const int k = 3; // can't change because the following loop + G2[] cVec = new G2[k]; + // init polynomial coefficient + for (int i = 0; i < k; i++) { + Fr x = new Fr(); + x.SetByCSPRNG(); + cVec[i].SetHashOf(x.GetStr(16)); + } + + Fr[] xVec = new Fr[n]; + G2[] yVec = new G2[n]; + // share cVec[0] with yVec[0], ..., yVec[n-1] + for (int i = 0; i < n; i++) { + xVec[i].SetHashOf(i.ToString()); + MCL.Share(ref yVec[i], cVec, xVec[i]); + } + // recover cVec[0] from xVecSubset and yVecSubset + Fr[] xVecSubset = new Fr[k]; + G2[] yVecSubset = new G2[k]; + for (int i0 = 0; i0 < n; i0++) { + xVecSubset[0] = xVec[i0]; + yVecSubset[0] = yVec[i0]; + for (int i1 = i0 + 1; i1 < n; i1++) { + xVecSubset[1] = xVec[i1]; + yVecSubset[1] = yVec[i1]; + for (int i2 = i1 + 1; i2 < n; i2++) { + xVecSubset[2] = xVec[i2]; + yVecSubset[2] = yVec[i2]; + G2 s = new G2(); + MCL.Recover(ref s, xVecSubset, yVecSubset); + assert("Recover", s.Equals(cVec[0])); + } + } + } + } + static void TestSS() + { + TestSS_Fr(); + TestSS_G1(); + TestSS_G2(); + } } } diff --git a/test/bench.hpp b/test/bench.hpp index d407bc7..cbe45e7 100644 --- a/test/bench.hpp +++ b/test/bench.hpp @@ -229,20 +229,32 @@ void testSquareRoot() void testLagrange() { puts("testLagrange"); - const int k = 7; - Fr c[k], x[k], y[k]; + const int n = 5; + const int k = 3; + Fr c[k]; + Fr x[n], y[n]; for (size_t i = 0; i < k; i++) { c[i].setByCSPRNG(); - x[i].setByCSPRNG(); } - for (size_t i = 0; i < k; i++) { + for (size_t i = 0; i < n; i++) { + x[i].setByCSPRNG(); mcl::evaluatePolynomial(y[i], c, k, x[i]); } - Fr s; - mcl::LagrangeInterpolation(s, x, y, k); - CYBOZU_TEST_EQUAL(s, c[0]); - mcl::LagrangeInterpolation(s, x, y, 1); - CYBOZU_TEST_EQUAL(s, y[0]); - mcl::evaluatePolynomial(y[0], c, 1, x[0]); - CYBOZU_TEST_EQUAL(y[0], c[0]); + Fr xs[k], ys[k]; + for (int i0 = 0; i0 < n; i0++) { + xs[0] = x[i0]; + ys[0] = y[i0]; + for (int i1 = i0 + 1; i1 < n; i1++) { + xs[1] = x[i1]; + ys[1] = y[i1]; + for (int i2 = i1 + 1; i2 < n; i2++) { + xs[2] = x[i2]; + ys[2] = y[i2]; + Fr s; + s.clear(); + mcl::LagrangeInterpolation(s, xs, ys, k); + CYBOZU_TEST_EQUAL(s, c[0]); + } + } + } }