You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@milagro.apache.org by km...@apache.org on 2020/02/21 14:17:12 UTC

[incubator-milagro-MPC] branch issue19 created (now 5698837)

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

kmccusker pushed a change to branch issue19
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-MPC.git.


      at 5698837  add BLS Python wrapper

This branch includes the following new commits:

     new 5698837  add BLS Python wrapper

The 1 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/01: add BLS Python wrapper

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

kmccusker pushed a commit to branch issue19
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-MPC.git

commit 5698837e3599564958af6071949131d3c08671ed
Author: Kealan McCusker <ke...@gmail.com>
AuthorDate: Fri Feb 21 14:16:52 2020 +0000

    add BLS Python wrapper
---
 Dockerfile                     |   2 +-
 python/amcl/bls.py             | 234 +++++++++++++++++++++++++++++++++++++++++
 python/examples/example_bls.py | 149 ++++++++++++++++++++++++++
 scripts/buildAMCL.sh           |   2 +-
 src/CMakeLists.txt             |   7 ++
 5 files changed, 392 insertions(+), 2 deletions(-)

diff --git a/Dockerfile b/Dockerfile
index 83ab0a2..ae6c905 100755
--- a/Dockerfile
+++ b/Dockerfile
@@ -58,7 +58,7 @@ RUN git clone https://github.com/apache/incubator-milagro-crypto-c.git && \
     cd incubator-milagro-crypto-c && \
     mkdir build && \
     cd build && \
-    cmake -D CMAKE_BUILD_TYPE=Release -D BUILD_SHARED_LIBS=ON -D AMCL_CHUNK=64 -D AMCL_CURVE="BLS381,SECP256K1" -D AMCL_RSA="" -D BUILD_PAILLIER=ON -D BUILD_PYTHON=ON -D BUILD_BLS=ON -D BUILD_WCC=OFF -D BUILD_MPIN=OFF -D BUILD_X509=OFF -D CMAKE_INSTALL_PREFIX=/usr/local .. && \
+    cmake -D CMAKE_BUILD_TYPE=Release -D BUILD_SHARED_LIBS=ON -D AMCL_CHUNK=64 -D AMCL_CURVE="BLS381,SECP256K1" -D AMCL_RSA="" -D BUILD_PAILLIER=ON -D BUILD_PYTHON=OFF -D BUILD_BLS=ON -D BUILD_WCC=OFF -D BUILD_MPIN=OFF -D BUILD_X509=OFF -D CMAKE_INSTALL_PREFIX=/usr/local .. && \
     make && \
     make test  ARGS=-j8 && \
     make install
diff --git a/python/amcl/bls.py b/python/amcl/bls.py
new file mode 100755
index 0000000..2a53ac4
--- /dev/null
+++ b/python/amcl/bls.py
@@ -0,0 +1,234 @@
+#!/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.
+"""
+
+
+"""
+bls
+
+This module use cffi to access the c functions in the BLS library.
+
+There is also an example usage program in this file.
+
+"""
+
+import platform
+from amcl import core_utils
+
+_ffi = core_utils._ffi
+_ffi.cdef("""
+extern int BLS_BLS381_KEY_PAIR_GENERATE(csprng *RNG,octet* S,octet *W);
+extern int BLS_BLS381_SIGN(octet *SIG,octet *m,octet *S);
+extern int BLS_BLS381_VERIFY(octet *SIG,octet *m,octet *W);
+extern int BLS_BLS381_ADD_G1(octet *R1,octet *R2,octet *R);
+extern int BLS_BLS381_ADD_G2(octet *W1,octet *W2,octet *W);
+""")
+
+if (platform.system() == 'Windows'):
+    _libamcl_bls_BLS381 = _ffi.dlopen("libamcl_bls_BLS381.dll")
+elif (platform.system() == 'Darwin'):
+    _libamcl_bls_BLS381 = _ffi.dlopen("libamcl_bls_BLS381.dylib")
+else:
+    _libamcl_bls_BLS381 = _ffi.dlopen("libamcl_bls_BLS381.so")
+
+# Group Size
+BGS = 48
+# Field Size
+BFS = 48
+
+CURVE_SECURITY = 128
+
+G1LEN = BFS + 1
+
+if CURVE_SECURITY == 128:
+    G2LEN = 4 * BFS
+
+if CURVE_SECURITY == 192:
+    G2LEN = 8 * BFS
+
+if CURVE_SECURITY == 256:
+    G2LEN = 16 * BFS
+
+
+def key_pair_generate(rng, sk=None):
+    """Generate key pair
+
+    Generate key pair
+
+    Args::
+
+        rng: Pointer to cryptographically secure pseudo-random number generator instance
+        sk: secret key. Externally generated
+
+    Returns::
+
+        error_code: error from the C function
+        sk: secret key
+        pk: public key
+
+    Raises:
+
+    """
+    if sk:
+        sk1, sk1_val = core_utils.make_octet(None, sk)
+        rng = _ffi.NULL
+    else:
+        sk1, sk1val = core_utils.make_octet(BGS)
+
+    pk1, pk1val = core_utils.make_octet(G2LEN)
+    error_code = _libamcl_bls_BLS381.BLS_BLS381_KEY_PAIR_GENERATE(rng, sk1, pk1)
+
+    sk = core_utils.to_str(sk1)
+    pk = core_utils.to_str(pk1)
+
+    # clear memory
+    core_utils.clear_octet(sk1)
+    core_utils.clear_octet(pk1)
+
+    return error_code, sk, pk
+
+
+def sign(message, sk):
+    """Calculate a signature
+
+    Generate key pair
+
+    Args::
+
+        message: Message to sign
+        sk: BLS secret key
+
+    Returns::
+
+        error_code: Zero for success or else an error code
+        signature: BLS signature
+
+    Raises:
+
+    """
+    m, m_val = core_utils.make_octet(None, message)
+    sk1, sk1_val = core_utils.make_octet(None, sk)
+    signature1, signature1_val = core_utils.make_octet(G1LEN)
+    error_code = _libamcl_bls_BLS381.BLS_BLS381_SIGN(signature1, m, sk1)
+
+    signature = core_utils.to_str(signature1)
+
+    # clear memory
+    core_utils.clear_octet(sk1)
+    core_utils.clear_octet(signature1)
+
+    return error_code, signature
+
+
+def verify(signature, message, pk):
+    """Verify a signature
+
+    Verify a signature
+
+    Args::
+
+        message: Message to verify
+        signature: BLS signature
+        pk: BLS public key
+
+    Returns::
+
+        error_code: Zero for success or else an error code
+
+    Raises:
+
+    """
+    m, m_val = core_utils.make_octet(None, message)
+    pk1, pk1_val = core_utils.make_octet(None, pk)
+    signature1, signature1_val = core_utils.make_octet(None, signature)
+    error_code = _libamcl_bls_BLS381.BLS_BLS381_VERIFY(signature1, m, pk1)
+
+    # clear memory
+    core_utils.clear_octet(pk1)
+    core_utils.clear_octet(signature1)
+
+    return error_code
+
+
+def add_G1(R1, R2):
+    """Add two members from the group G1
+
+    Add two members from the group G1
+
+    Args::
+
+        R1:   member of G1
+        R2:   member of G1
+
+    Returns::
+
+        R:          member of G1. R = R1+R2
+        error_code: Zero for success or else an error code
+
+    Raises:
+
+    """
+    R11, R11_val = core_utils.make_octet(None, R1)
+    R21, R21_val = core_utils.make_octet(None, R2)
+    R1, R1_val = core_utils.make_octet(G1LEN)
+    error_code = _libamcl_bls_BLS381.BLS_BLS381_ADD_G1(R11, R21, R1)
+
+    R = core_utils.to_str(R1)
+
+    # clear memory
+    core_utils.clear_octet(R11)
+    core_utils.clear_octet(R21)
+    core_utils.clear_octet(R1)
+
+    return error_code, R
+
+
+def add_G2(R1, R2):
+    """Add two members from the group G2
+
+    Add two members from the group G2
+
+    Args::
+
+        R1:   member of G2
+        R2:   member of G2
+
+    Returns::
+
+        R:          member of G2. R = R1+R2
+        error_code: Zero for success or else an error code
+
+    Raises:
+
+    """
+    R11, R11_val = core_utils.make_octet(None, R1)
+    R21, R21_val = core_utils.make_octet(None, R2)
+    R1, R1_val = core_utils.make_octet(G2LEN)
+    error_code = _libamcl_bls_BLS381.BLS_BLS381_ADD_G2(R11, R21, R1)
+
+    R = core_utils.to_str(R1)
+
+    # clear memory
+    core_utils.clear_octet(R11)
+    core_utils.clear_octet(R21)
+    core_utils.clear_octet(R1)
+
+    return error_code, R
+
diff --git a/python/examples/example_bls.py b/python/examples/example_bls.py
new file mode 100755
index 0000000..33075d1
--- /dev/null
+++ b/python/examples/example_bls.py
@@ -0,0 +1,149 @@
+#!/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, bls
+
+if __name__ == "__main__":
+    # Print hex values
+    DEBUG = False
+
+    # Seed
+    seed_hex = "78d0fb6705ce77dee47d03eb5b9c5d30"
+    seed = bytes.fromhex(seed_hex)
+
+    # Message
+    message = b"test message"
+
+    # random number generator
+    rng = core_utils.create_csprng(seed)
+
+    # Generate key pairs
+    rtn, sk1, pktmp = bls.key_pair_generate(rng)
+    if rtn != 0:
+        print("Error: key_pair_generate {}".format(rtn))
+        raise SystemExit(0)
+    print("sk1: {}".format(sk1.hex()))
+    print("pktmp: {}".format(pktmp.hex()))
+
+    rtn, sk1, pk1 = bls.key_pair_generate(rng, sk1)
+    if rtn != 0:
+        print("Error: key_pair_generate {}".format(rtn))
+        raise SystemExit(0)
+    print("sk1: {}".format(sk1.hex()))
+    print("pk1: {}".format(pk1.hex()))
+
+    rtn, sk2, pk2 = bls.key_pair_generate(rng)
+    if rtn != 0:
+        print("Error: key_pair_generate {}".format(rtn))
+        raise SystemExit(0)
+    print("sk2: {}".format(sk2.hex()))
+    print("pk2: {}".format(pk2.hex()))
+
+    rtn, sk3, pk3 = bls.key_pair_generate(rng)
+    if rtn != 0:
+        print("Error: key_pair_generate {}".format(rtn))
+        raise SystemExit(0)
+    print("sk3: {}".format(sk3.hex()))
+    print("pk3: {}".format(pk3.hex()))
+
+    # Sign and verify
+    rtn, sig1 = bls.sign(message, sk1)
+    if rtn != 0:
+        print("Error: sign {}".format(rtn))
+        raise SystemExit(0)
+    print("sig1: {}".format(sig1.hex()))
+
+    rtn = bls.verify(sig1, message, pk1)
+    if rtn != 0:
+        print("Error: Invalid signature {}".format(rtn))
+        raise SystemExit(0)
+    print("Success: Signature is valid")
+
+    rtn, sig2 = bls.sign(message, sk2)
+    if rtn != 0:
+        print("Error: sign {}".format(rtn))
+        raise SystemExit(0)
+    print("sig2: {}".format(sig2.hex()))
+
+    rtn = bls.verify(sig2, message, pk2)
+    if rtn != 0:
+        print("Error: Invalid signature {}".format(rtn))
+        raise SystemExit(0)
+    print("Success: Signature is valid")
+
+    rtn, sig3 = bls.sign(message, sk3)
+    if rtn != 0:
+        print("Error: sign {}".format(rtn))
+        raise SystemExit(0)
+    print("sig3: {}".format(sig3.hex()))
+
+    rtn = bls.verify(sig3, message, pk3)
+    if rtn != 0:
+        print("Error: Invalid signature {}".format(rtn))
+        raise SystemExit(0)
+    print("Success: Signature is valid")
+
+    # Add Signatures
+    rtn, sig12 = bls.add_G1(sig1, sig2)
+    if rtn != 0:
+        print("Error: add_G1 {}".format(rtn))
+        raise SystemExit(0)
+    print("sig12: {}".format(sig12.hex()))
+
+    rtn, sig123 = bls.add_G1(sig12, sig3)
+    if rtn != 0:
+        print("Error: add_G1 {}".format(rtn))
+        raise SystemExit(0)
+    print("sig123: {}".format(sig123.hex()))
+
+    # Add Public keys
+    rtn, pk12 = bls.add_G2(pk1, pk2)
+    if rtn != 0:
+        print("Error: add_G2 {}".format(rtn))
+        raise SystemExit(0)
+    print("pk12: {}".format(pk12.hex()))
+
+    rtn, pk123 = bls.add_G2(pk12, pk3)
+    if rtn != 0:
+        print("Error: add_G2 {}".format(rtn))
+        raise SystemExit(0)
+    print("pk123: {}".format(pk123.hex()))
+
+    # Verify aggretated values
+    rtn = bls.verify(sig123, message, pk123)
+    if rtn != 0:
+        print("Error: Invalid aggregated signature {}".format(rtn))
+        raise SystemExit(0)
+    print("Success: Aggregated signature is valid")
+
+    # Clear memory
+    core_utils.kill_csprng(rng)
+    del sk1
+    del pk1
+    del sk2
+    del pk2
+    del sk3
+    del pk3
diff --git a/scripts/buildAMCL.sh b/scripts/buildAMCL.sh
index 137d09e..e612cb5 100755
--- a/scripts/buildAMCL.sh
+++ b/scripts/buildAMCL.sh
@@ -15,7 +15,7 @@ git clone https://github.com/apache/incubator-milagro-crypto-c.git
 cd incubator-milagro-crypto-c
 mkdir build
 cd build
-cmake -D CMAKE_BUILD_TYPE=Debug -D BUILD_SHARED_LIBS=ON -D AMCL_CHUNK=64 -D AMCL_CURVE="BLS381,SECP256K1" -D AMCL_RSA="" -D BUILD_PAILLIER=ON -D BUILD_PYTHON=ON -D BUILD_BLS=ON -D BUILD_WCC=OFF -D BUILD_MPIN=ON -D BUILD_X509=OFF -D CMAKE_INSTALL_PREFIX=/usr/local ..
+cmake -D CMAKE_BUILD_TYPE=Debug -D BUILD_SHARED_LIBS=ON -D AMCL_CHUNK=64 -D AMCL_CURVE="BLS381,SECP256K1" -D AMCL_RSA="" -D BUILD_PAILLIER=ON -D BUILD_PYTHON=OFF -D BUILD_BLS=ON -D BUILD_WCC=OFF -D BUILD_MPIN=ON -D BUILD_X509=OFF -D CMAKE_INSTALL_PREFIX=/usr/local ..
 make
 make test ARGS=-j8
 sudo make install
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1311df2..f6c45db 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -39,3 +39,10 @@ install(TARGETS ${target} DESTINATION lib PERMISSIONS
   OWNER_WRITE OWNER_READ OWNER_EXECUTE
   GROUP_READ GROUP_EXECUTE
   WORLD_READ WORLD_EXECUTE)
+
+if(BUILD_PYTHON)
+  message(STATUS "Copy ${target} library to python directory for testing")
+  add_custom_command(TARGET ${target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_BINARY_DIR}/lib*" "${PROJECT_BINARY_DIR}/python/test")
+  add_custom_command(TARGET ${target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_BINARY_DIR}/lib*" "${PROJECT_BINARY_DIR}/python/benchmark")
+  add_custom_command(TARGET ${target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_BINARY_DIR}/lib*" "${PROJECT_BINARY_DIR}/python/examples")  
+endif(BUILD_PYTHON)