You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@milagro.apache.org by sa...@apache.org on 2020/02/19 16:00:35 UTC

[incubator-milagro-MPC] branch issue8-nm-commit-wrapper created (now 7553c2d)

This is an automated email from the ASF dual-hosted git repository.

sandreoli pushed a change to branch issue8-nm-commit-wrapper
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-MPC.git.


      at 7553c2d  format code

This branch includes the following new commits:

     new 33e0128  Add NM commit wrappers with test, benchmark and example
     new 7553c2d  format code

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[incubator-milagro-MPC] 01/02: Add NM commit wrappers with test, benchmark and example

Posted by sa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sandreoli pushed a commit to branch issue8-nm-commit-wrapper
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-MPC.git

commit 33e01281b0b56cac540c585ff9b992558d3b8145
Author: Samuele Andreoli <sa...@yahoo.it>
AuthorDate: Tue Feb 18 16:40:26 2020 +0000

    Add NM commit wrappers with test, benchmark and example
---
 python/amcl/commitments.py             | 222 +++++++++++++++++++++++++++++++++
 python/benchmark/bench_nm_commit.py    |  47 +++++++
 python/examples/example_nm_commit.py   |  54 ++++++++
 python/test/CMakeLists.txt             |  16 ++-
 python/test/test_nm_commit.py          |  90 +++++++++++++
 testVectors/commitments/nm_commit.json |  62 +++++++++
 6 files changed, 486 insertions(+), 5 deletions(-)

diff --git a/python/amcl/commitments.py b/python/amcl/commitments.py
new file mode 100644
index 0000000..153addd
--- /dev/null
+++ b/python/amcl/commitments.py
@@ -0,0 +1,222 @@
+#!/usr/bin/env python3
+
+"""
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+"""
+
+"""
+
+This module use cffi to access the c functions in the amcl_mpc library.
+
+"""
+import platform
+from amcl import core_utils
+
+_ffi = core_utils._ffi
+_ffi.cdef("""
+extern void COMMITMENTS_NM_commit(csprng *RNG, octet *X, octet *R, octet *C);
+extern int COMMITMENTS_NM_decommit(octet* X, octet* R, octet* C);
+""")
+
+if (platform.system() == 'Windows'):
+    libamcl_mpc = _ffi.dlopen("libamcl_mpc.dll")
+    libamcl_core = _ffi.dlopen("libamcl_core.dll")
+elif (platform.system() == 'Darwin'):
+    libamcl_mpc = _ffi.dlopen("libamcl_mpc.dylib")
+    libamcl_core = _ffi.dlopen("libamcl_core.dylib")
+else:
+    libamcl_mpc = _ffi.dlopen("libamcl_mpc.so")
+    libamcl_core = _ffi.dlopen("libamcl_core.so")
+
+# Constants
+SHA256 = 32
+
+OK   = 0
+FAIL = 81
+
+
+def to_str(octet_value):
+    """Converts an octet type into a string
+
+    Add all the values in an octet into an array.
+
+    Args::
+
+        octet_value. An octet pointer type
+
+    Returns::
+
+        String
+
+    Raises:
+        Exception
+    """
+    i = 0
+    val = []
+    while i < octet_value.len:
+        val.append(octet_value.val[i])
+        i = i + 1
+    out = b''
+    for x in val:
+        out = out + x
+    return out
+
+
+def make_octet(length, value=None):
+    """Generates an octet pointer
+
+    Generates an empty octet or one filled with the input value
+
+    Args::
+
+        length: Length of empty octet
+        value:  Data to assign to octet
+
+    Returns::
+
+        oct_ptr: octet pointer
+        val: data associated with octet to prevent garbage collection
+
+    Raises:
+
+    """
+    oct_ptr = _ffi.new("octet*")
+    if value:
+        val = _ffi.new("char [%s]" % len(value), value)
+        oct_ptr.val = val
+        oct_ptr.max = len(value)
+        oct_ptr.len = len(value)
+    else:
+        val = _ffi.new("char []", length)
+        oct_ptr.val = val
+        oct_ptr.max = length
+        oct_ptr.len = 0
+    return oct_ptr, val
+
+
+def create_csprng(seed):
+    """Make a Cryptographically secure pseudo-random number generator instance
+
+    Make a Cryptographically secure pseudo-random number generator instance
+
+    Args::
+
+        seed:   random seed value
+
+    Returns::
+
+        rng: Pointer to cryptographically secure pseudo-random number generator instance
+
+    Raises:
+
+    """
+    seed_val = _ffi.new("char [%s]" % len(seed), seed)
+    seed_len = len(seed)
+
+    # random number generator
+    rng = _ffi.new('csprng*')
+    libamcl_core.RAND_seed(rng, seed_len, seed_val)
+
+    return rng
+
+
+def kill_csprng(rng):
+    """Kill a random number generator
+
+    Deletes all internal state
+
+    Args::
+
+        rng: Pointer to cryptographically secure pseudo-random number generator instance
+
+    Returns::
+
+    Raises:
+
+    """
+    libamcl_core.RAND_clean(rng)
+
+    return 0
+
+
+def nm_commit(rng, x, r=None):
+    """ Commit to the value x
+
+    Generate a commitment c to the value x, using the value r.
+    If r is empty it is randomly generated
+
+    Args::
+
+        rng : Pointer to cryptographically secure pseudo-random generator instance
+        x   : value to commit
+        r   : random value for the commitment. If empty it is randomly generated
+              If not empty it must be 256 bit long
+
+    Returns::
+
+    Raises::
+
+    """
+
+    if r is None:
+        r_oct, r_val = make_octet(SHA256)
+    else:
+        r_oct, r_val = make_octet(None, r)
+        rng = _ffi.NULL
+
+    _ = r_val # Suppress warning
+
+    x_oct, x_val = make_octet(None, x)
+    c_oct, c_val = make_octet(SHA256)
+    _ = x_val, c_val # Suppress warning
+
+    libamcl_mpc.COMMITMENTS_NM_commit(rng, x_oct, r_oct, c_oct)
+
+    r = to_str(r_oct)
+
+    # Clean memory
+    libamcl_core.OCT_clear(x_oct)
+    libamcl_core.OCT_clear(r_oct)
+
+    return r, to_str(c_oct)
+
+def nm_decommit(x, r, c):
+    """ Decommit commitment c
+
+    Decommit a commitment c to the value x, using the value r.
+
+    Args::
+
+        x : value to commit
+        r : random value for the commitment. It must be 256 bit
+        c : commitment value
+
+    Returns::
+
+    Raises::
+
+    """
+
+    x_oct, x_val = make_octet(None, x)
+    r_oct, r_val = make_octet(None, r)
+    c_oct, c_val = make_octet(None, c)
+    _ = x_val, r_val, c_val # Suppress warning
+
+    ec = libamcl_mpc.COMMITMENTS_NM_decommit(x_oct, r_oct, c_oct)
+
+    return ec
diff --git a/python/benchmark/bench_nm_commit.py b/python/benchmark/bench_nm_commit.py
new file mode 100755
index 0000000..a10012e
--- /dev/null
+++ b/python/benchmark/bench_nm_commit.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python3
+
+"""
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+"""
+
+import os
+import sys
+from bench import time_func
+
+sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
+
+from amcl import commitments
+
+x_hex = "40576370e36018f6bfaffc4c66780303a361f0c5f4a18a86a74fb179ca0fcf22"
+r_hex = "296f910bde4530efe3533ed3b74475d6022364db2e57773207734b6daf547ac8"
+
+if __name__ == "__main__":
+    x = bytes.fromhex(x_hex)
+    r = bytes.fromhex(r_hex)
+
+    # Generate quantities for benchmark
+    r, c = commitments.nm_commit(None, x, r)
+
+    assert commitments.nm_decommit(x, r, c) == commitments.OK
+
+    # Run benchmark
+    fncall = lambda: commitments.nm_commit(None, x, r)
+    time_func("nm_commit  ", fncall, unit="us")
+
+    fncall = lambda: commitments.nm_decommit(x, r, c)
+    time_func("nm_decommit", fncall, unit="us")
diff --git a/python/examples/example_nm_commit.py b/python/examples/example_nm_commit.py
new file mode 100755
index 0000000..024e60c
--- /dev/null
+++ b/python/examples/example_nm_commit.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python3
+
+"""
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+"""
+
+import os
+import sys
+
+sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
+
+from amcl import core_utils, commitments
+
+seed_hex = "78d0fb6705ce77dee47d03eb5b9c5d30"
+
+if __name__ == "__main__":
+    seed = bytes.fromhex(seed_hex)
+    rng = core_utils.create_csprng(seed)
+
+    print("Example Non Malleable Commitment")
+    print("Message: BANANA")
+
+    x = b'BANANA'
+
+    # Commitment Phase
+    r, c = commitments.nm_commit(rng, x)
+
+    print("\nCommitment")
+    print(f"\tr = {r.hex()}")
+    print(f"\tc = {c.hex()}")
+
+    # Decommitment Phase. After both c, r and x have been revealed
+    rc = commitments.nm_decommit(x, r, c)
+
+    print("\nDecommitment")
+    if rc == commitments.OK:
+        print("\tSuccess")
+    else:
+        print("\tFailure")
diff --git a/python/test/CMakeLists.txt b/python/test/CMakeLists.txt
index a01ddf4..b2fdbc7 100644
--- a/python/test/CMakeLists.txt
+++ b/python/test/CMakeLists.txt
@@ -44,10 +44,16 @@ file(COPY ${MPC_TV} DESTINATION "${PROJECT_BINARY_DIR}/python/test/mpc/")
 file(GLOB SCHNORR_TV "${PROJECT_SOURCE_DIR}/testVectors/schnorr/*.json")
 file(COPY ${SCHNORR_TV} DESTINATION "${PROJECT_BINARY_DIR}/python/test/schnorr/")
 
+# NM Commitment test vector
+file(
+  COPY ${PROJECT_SOURCE_DIR}/testVectors/commitments/nm_commit.json
+  DESTINATION "${PROJECT_BINARY_DIR}/python/test/commitments/")
+
 if(NOT CMAKE_BUILD_TYPE STREQUAL "ASan")
-  add_python_test(test_python_mpc_mta     test_mta.py)
-  add_python_test(test_python_mpc_r       test_r.py)
-  add_python_test(test_python_mpc_s       test_s.py)
-  add_python_test(test_python_mpc_ecdsa   test_ecdsa.py)
-  add_python_test(test_python_mpc_schnorr test_schnorr.py)
+  add_python_test(test_python_mpc_mta       test_mta.py)
+  add_python_test(test_python_mpc_r         test_r.py)
+  add_python_test(test_python_mpc_s         test_s.py)
+  add_python_test(test_python_mpc_ecdsa     test_ecdsa.py)
+  add_python_test(test_python_mpc_schnorr   test_schnorr.py)
+  add_python_test(test_python_mpc_nm_commit test_nm_commit.py)
 endif(NOT CMAKE_BUILD_TYPE STREQUAL "ASan")
diff --git a/python/test/test_nm_commit.py b/python/test/test_nm_commit.py
new file mode 100755
index 0000000..a317a79
--- /dev/null
+++ b/python/test/test_nm_commit.py
@@ -0,0 +1,90 @@
+#!/usr/bin/env python3
+
+"""
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+"""
+
+import os
+import sys
+import json
+from unittest import TestCase
+
+sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
+
+from amcl import commitments, core_utils
+
+# Load and preprocess test vectors
+with open("commitments/nm_commit.json", "r") as f:
+    vectors = json.load(f)
+
+for vector in vectors:
+    for key, val in vector.items():
+        if key != "TEST":
+            vector[key] = bytes.fromhex(val)
+
+
+class TestNMCommit(TestCase):
+    """ Test NM Commitment Commit """
+
+    def setUp(self):
+        # Deterministic PRNG for testing purposes
+        seed_hex = "78d0fb6705ce77dee47d03eb5b9c5d30"
+        seed = bytes.fromhex(seed_hex)
+        self.rng = core_utils.create_csprng(seed)
+
+        self.msg = b'BANANA'
+
+        r_hex = "296f910bde4530efe3533ed3b74475d6022364db2e57773207734b6daf547ac8"
+        c_hex = "b60ebd5193252d22c771a7702724e9922662aae5f634494225cdd3a9e22f9826"
+        self.r_golden = bytes.fromhex(r_hex)
+        self.c_golden = bytes.fromhex(c_hex)
+
+    def test_tv(self):
+        """ Test using test vectors """
+
+        for vector in vectors:
+            r, c = commitments.nm_commit(None, vector['X'], vector['R'])
+
+            self.assertEqual(vector['R'], r)
+            self.assertEqual(vector['C'], c)
+
+    def test_random(self):
+        """ Test using rng """
+        r, c = commitments.nm_commit(self.rng, self.msg)
+
+        self.assertEqual(r, self.r_golden)
+        self.assertEqual(c, self.c_golden)
+
+
+class TestNMDecommit(TestCase):
+    """ Test NM Commitment Decommit """
+
+    def test_tv(self):
+        """ Test using test vectors """
+
+        for vector in vectors:
+            rc = commitments.nm_decommit(vector['X'], vector['R'], vector['C'])
+
+            self.assertEqual(rc, commitments.OK)
+
+    def test_failure(self):
+        """ Test error codes are propagated correctly """
+
+        rc = commitments.nm_decommit(vector['X'], vector['X'], vector['C'])
+
+        self.assertEqual(rc, commitments.FAIL)
diff --git a/testVectors/commitments/nm_commit.json b/testVectors/commitments/nm_commit.json
new file mode 100644
index 0000000..aa506a3
--- /dev/null
+++ b/testVectors/commitments/nm_commit.json
@@ -0,0 +1,62 @@
+[
+    {
+        "TEST":"0",
+        "X": "3f3cc85d2a99534d",
+        "R": "bba1e28251a39a13c037b180ed41cb76c23ca5fd639725706ead86f40d7f7b1e",
+        "C": "d49772a2af3c0904199b5620014f34ee2152cb427a4f241b2e45c62ce1a11f69"
+    },
+    {
+        "TEST": "1",
+        "X": "e8687750094198b455",
+        "R": "3ec7e47abe1345061e4c54808779c43493e4b6d15749d33becd1efb418ec0d34",
+        "C": "4eb9edfe9b66dcdb1882a9ea862794b2308d9a768155e96810502cc361f2afcc"
+    },
+    {
+        "TEST": "2",
+        "X": "ed45810ce81e4bf27980",
+        "R": "18a8edb9f5211df1f0f876e012a1404973cd173acea497d6fb93b5b39b910a89",
+        "C": "52bf67e6e9f4fd68382d2c94dc4044191edf5005cbbfa2cea6a6c7b69846e043"
+    },
+    {
+        "TEST": "3",
+        "X": "965f61c651654622880bcc",
+        "R": "88a038a78dba707e72b192eef24aab965335c51c3e15e39b132229807c828c23",
+        "C": "7e1c0cbcc37b311cabe367bdd85dcacc1fc5e5dcbb374bf12ea224832a6ad91c"
+    },
+    {
+        "TEST": "4",
+        "X": "311b616d5e92ea7e7d6bb8e2",
+        "R": "ec3712c94f66098933c57abbc46c4298bb276eceac3597654e1fd72ba434191d",
+        "C": "a6b6083665669c6de43d0dcd15f29964ffcd9075ecd46ca8e58711ab359002c3"
+    },
+    {
+        "TEST": "5",
+        "X": "1ce58293a6ab70f62b4c724e60",
+        "R": "1c4c20f3d10a5af166e45afbc88c98008fff529b6cc8ce008d375848712a0778",
+        "C": "90986555e5c9bbace9048913ef0eb44a06ed8b5dd76ae3090b4911c6fa2b4d7b"
+    },
+    {
+        "TEST": "6",
+        "X": "e1c508ee1862474e1080bbaefe89",
+        "R": "4d812c8519837c696dc1967adb2452972119bea337174182768fd0f781d41b6d",
+        "C": "83594768dbd29e0fc7dedc0dd999e573a478292305d6764ed3b981d26cc55666"
+    },
+    {
+        "TEST": "7",
+        "X": "df5b2f3e4a2f35e81dc93f9d33b540",
+        "R": "4d9112b5f3b34a3e6db75078e48006b8d86459cfb9ea9093272c416a56a4794b",
+        "C": "e8d031761ed9ab072dec45457710ce7a7d88695b854b8fbd42a06387972cbb79"
+    },
+    {
+        "TEST": "8",
+        "X": "966244192989663e85ee431f90182539",
+        "R": "e330c3a33e2657eca224e778952e1abfde0ca62f8da0417ca64d34b2bb16de3f",
+        "C": "1ef1b10077de18cda783dbbeeefaacc93051d2456e6fc53958506ff1cfda064c"
+    },
+    {
+        "TEST": "9",
+        "X": "76cba6658a3730513c7b7cd2135e3e1f16",
+        "R": "40576370e36018f6bfaffc4c66780303a361f0c5f4a18a86a74fb179ca0fcf22",
+        "C": "88c318a79e481cc7ce7041bb3e66e50cbae6b88efaaa649a4b6b06fb6351b952"
+    }
+]


[incubator-milagro-MPC] 02/02: format code

Posted by sa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sandreoli pushed a commit to branch issue8-nm-commit-wrapper
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-MPC.git

commit 7553c2d112b4a96411062bf9dffed9bee151bb98
Author: Samuele Andreoli <sa...@yahoo.it>
AuthorDate: Wed Feb 19 13:20:19 2020 +0000

    format code
---
 benchmark/bench.h                 | 2 +-
 examples/example_dump_keys.c      | 4 ++--
 test/smoke/test_dump_keys_smoke.c | 6 +++---
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/benchmark/bench.h b/benchmark/bench.h
index 5c60bc5..6472bf5 100644
--- a/benchmark/bench.h
+++ b/benchmark/bench.h
@@ -41,4 +41,4 @@ extern void print_system_info();
 }
 #endif
 
-#endif
\ No newline at end of file
+#endif
diff --git a/examples/example_dump_keys.c b/examples/example_dump_keys.c
index ccf0f84..0320c01 100644
--- a/examples/example_dump_keys.c
+++ b/examples/example_dump_keys.c
@@ -50,7 +50,7 @@ int main()
     PAILLIER_public_key PUB1;
     PAILLIER_private_key PRIV2;
     PAILLIER_public_key PUB2;
-    PAILLIER_public_key PUB3;    
+    PAILLIER_public_key PUB3;
 
     // Paillier public key
     char n[FS_4096] = {0};
@@ -73,7 +73,7 @@ int main()
 
     FF_2048_toOctet(&P, PRIV1.p, HFLEN_2048);
     FF_2048_toOctet(&Q, PRIV1.q, HFLEN_2048);
-    
+
     // Write secret key to octets
     MPC_DUMP_PAILLIER_SK(&PRIV1, &P, &Q);
 
diff --git a/test/smoke/test_dump_keys_smoke.c b/test/smoke/test_dump_keys_smoke.c
index 751941d..5ba8799 100644
--- a/test/smoke/test_dump_keys_smoke.c
+++ b/test/smoke/test_dump_keys_smoke.c
@@ -53,7 +53,7 @@ int main()
     PAILLIER_private_key PRIV2;
     PAILLIER_public_key PUB2;
     PAILLIER_public_key PUB3;
-    
+
     char p[FS_2048] = {0};
     octet P = {0,sizeof(p),p};
 
@@ -180,9 +180,9 @@ int main()
         fprintf(stderr, "FAILURE QQ != Q rc: %d\n", rc);
         exit(EXIT_FAILURE);
     }
-    
+
     // Read secret key from octets
-    PAILLIER_KEY_PAIR(NULL, &PP, &QQ, &PUB3, &PRIV2);    
+    PAILLIER_KEY_PAIR(NULL, &PP, &QQ, &PUB3, &PRIV2);
 
     MPC_MTA_CLIENT1(NULL, &PUB2, &A, &CA, &R);