blob: 5f27eb1e70ec8a3a5d42c2804cfad12f1871d47c [file] [log] [blame]
#!/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 . 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