Blind signature support in pyelliptic
- add blind signature functionality to pyelliptic as described in #1409 - add tests for blind signatures - PEP8 fixes for pyelliptic - some minor refactoring is necessary for further integration, this is just a minimal implementation to pass a test
This commit is contained in:
parent
f180b1a5b0
commit
2e0f7755c6
|
@ -2,18 +2,20 @@
|
||||||
# Author: Yann GUIBET
|
# Author: Yann GUIBET
|
||||||
# Contact: <yannguibet@gmail.com>
|
# Contact: <yannguibet@gmail.com>
|
||||||
|
|
||||||
|
from .openssl import OpenSSL
|
||||||
|
from .ecc import ECC
|
||||||
|
from .eccblind import ECCBlind
|
||||||
|
from .cipher import Cipher
|
||||||
|
from .hash import hmac_sha256, hmac_sha512, pbkdf2
|
||||||
|
|
||||||
__version__ = '1.3'
|
__version__ = '1.3'
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'OpenSSL',
|
'OpenSSL',
|
||||||
'ECC',
|
'ECC',
|
||||||
|
'ECCBlind',
|
||||||
'Cipher',
|
'Cipher',
|
||||||
'hmac_sha256',
|
'hmac_sha256',
|
||||||
'hmac_sha512',
|
'hmac_sha512',
|
||||||
'pbkdf2'
|
'pbkdf2'
|
||||||
]
|
]
|
||||||
|
|
||||||
from .openssl import OpenSSL
|
|
||||||
from .ecc import ECC
|
|
||||||
from .cipher import Cipher
|
|
||||||
from .hash import hmac_sha256, hmac_sha512, pbkdf2
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
# Copyright (C) 2011 Yann GUIBET <yannguibet@gmail.com>
|
# Copyright (C) 2011 Yann GUIBET <yannguibet@gmail.com>
|
||||||
# See LICENSE for details.
|
# See LICENSE for details.
|
||||||
|
|
||||||
from pyelliptic.openssl import OpenSSL
|
from openssl import OpenSSL
|
||||||
|
|
||||||
|
|
||||||
class Cipher:
|
class Cipher:
|
||||||
|
|
|
@ -12,9 +12,9 @@ src/pyelliptic/ecc.py
|
||||||
from hashlib import sha512
|
from hashlib import sha512
|
||||||
from struct import pack, unpack
|
from struct import pack, unpack
|
||||||
|
|
||||||
from pyelliptic.cipher import Cipher
|
from cipher import Cipher
|
||||||
from pyelliptic.hash import equals, hmac_sha256
|
from hash import equals, hmac_sha256
|
||||||
from pyelliptic.openssl import OpenSSL
|
from openssl import OpenSSL
|
||||||
|
|
||||||
|
|
||||||
class ECC(object):
|
class ECC(object):
|
||||||
|
|
179
src/pyelliptic/eccblind.py
Normal file
179
src/pyelliptic/eccblind.py
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
"""
|
||||||
|
ECC blind signature functionality based on "An Efficient Blind Signature Scheme
|
||||||
|
Based on the Elliptic CurveDiscrete Logarithm Problem" by Morteza Nikooghadama
|
||||||
|
<mnikooghadam@sbu.ac.ir> and Ali Zakerolhosseini <a-zaker@sbu.ac.ir>,
|
||||||
|
http://www.isecure-journal.com/article_39171_47f9ec605dd3918c2793565ec21fcd7a.pdf
|
||||||
|
"""
|
||||||
|
|
||||||
|
# variable names are based on the math in the paper, so they don't conform
|
||||||
|
# to PEP8
|
||||||
|
# pylint: disable=invalid-name
|
||||||
|
|
||||||
|
from .openssl import OpenSSL
|
||||||
|
|
||||||
|
|
||||||
|
class ECCBlind(object): # pylint: disable=too-many-instance-attributes
|
||||||
|
"""
|
||||||
|
Class for ECC blind signature functionality
|
||||||
|
"""
|
||||||
|
|
||||||
|
# init
|
||||||
|
k = None
|
||||||
|
R = None
|
||||||
|
keypair = None
|
||||||
|
F = None
|
||||||
|
Q = None
|
||||||
|
a = None
|
||||||
|
b = None
|
||||||
|
c = None
|
||||||
|
binv = None
|
||||||
|
r = None
|
||||||
|
m = None
|
||||||
|
m_ = None
|
||||||
|
s_ = None
|
||||||
|
signature = None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def ec_get_random(group, ctx):
|
||||||
|
"""
|
||||||
|
Random point from finite field
|
||||||
|
"""
|
||||||
|
order = OpenSSL.BN_new()
|
||||||
|
OpenSSL.EC_GROUP_get_order(group, order, ctx)
|
||||||
|
OpenSSL.BN_rand(order, OpenSSL.BN_num_bits(order), 0, 0)
|
||||||
|
return order
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def ec_invert(group, a, ctx):
|
||||||
|
"""
|
||||||
|
ECC inversion
|
||||||
|
"""
|
||||||
|
order = OpenSSL.BN_new()
|
||||||
|
OpenSSL.EC_GROUP_get_order(group, order, ctx)
|
||||||
|
inverse = OpenSSL.BN_mod_inverse(0, a, order, ctx)
|
||||||
|
return inverse
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def ec_gen_keypair(group, ctx):
|
||||||
|
"""
|
||||||
|
Generate an ECC keypair
|
||||||
|
"""
|
||||||
|
d = ECCBlind.ec_get_random(group, ctx)
|
||||||
|
Q = OpenSSL.EC_POINT_new(group)
|
||||||
|
OpenSSL.EC_POINT_mul(group, Q, d, 0, 0, 0)
|
||||||
|
return (d, Q)
|
||||||
|
|
||||||
|
def __init__(self, curve="secp256k1"):
|
||||||
|
self.group = OpenSSL.EC_GROUP_new_by_curve_name(OpenSSL.get_curve(curve))
|
||||||
|
self.ctx = OpenSSL.BN_CTX_new()
|
||||||
|
|
||||||
|
# Order n
|
||||||
|
self.n = OpenSSL.BN_new()
|
||||||
|
OpenSSL.EC_GROUP_get_order(self.group, self.n, self.ctx)
|
||||||
|
|
||||||
|
# Identity O (infinity)
|
||||||
|
self.iO = OpenSSL.EC_POINT_new(self.group)
|
||||||
|
OpenSSL.EC_POINT_set_to_infinity(self.group, self.iO)
|
||||||
|
|
||||||
|
# Generator G
|
||||||
|
self.G = OpenSSL.EC_GROUP_get0_generator(self.group)
|
||||||
|
|
||||||
|
# Certifier's pubkey
|
||||||
|
self.pubkey = (self.group, self.G, self.n)
|
||||||
|
|
||||||
|
def signer_init(self):
|
||||||
|
"""
|
||||||
|
Init signer
|
||||||
|
"""
|
||||||
|
# Signer: Random integer k
|
||||||
|
self.k = ECCBlind.ec_get_random(self.group, self.ctx)
|
||||||
|
|
||||||
|
# R = kG
|
||||||
|
self.R = OpenSSL.EC_POINT_new(self.group)
|
||||||
|
OpenSSL.EC_POINT_mul(self.group, self.R, self.k, 0, 0, 0)
|
||||||
|
|
||||||
|
def create_signing_request(self, msg):
|
||||||
|
"""
|
||||||
|
Requester creates a new signing request
|
||||||
|
"""
|
||||||
|
# new keypair
|
||||||
|
self.keypair = ECCBlind.ec_gen_keypair(self.group, self.ctx)
|
||||||
|
|
||||||
|
# Requester: 3 random blinding factors
|
||||||
|
self.F = OpenSSL.EC_POINT_new(self.group)
|
||||||
|
OpenSSL.EC_POINT_set_to_infinity(self.group, self.F)
|
||||||
|
temp = OpenSSL.EC_POINT_new(self.group)
|
||||||
|
self.Q = self.keypair[1]
|
||||||
|
abinv = OpenSSL.BN_new()
|
||||||
|
|
||||||
|
# F != O
|
||||||
|
while OpenSSL.EC_POINT_cmp(self.group, self.F, self.iO, self.ctx) == 0:
|
||||||
|
self.a = ECCBlind.ec_get_random(self.group, self.ctx)
|
||||||
|
self.b = ECCBlind.ec_get_random(self.group, self.ctx)
|
||||||
|
self.c = ECCBlind.ec_get_random(self.group, self.ctx)
|
||||||
|
|
||||||
|
# F = b^-1 * R...
|
||||||
|
self.binv = ECCBlind.ec_invert(self.group, self.b, self.ctx)
|
||||||
|
OpenSSL.EC_POINT_mul(self.group, temp, 0, self.R, self.binv, 0)
|
||||||
|
OpenSSL.EC_POINT_copy(self.F, temp)
|
||||||
|
|
||||||
|
# ... + a*b^-1 * Q...
|
||||||
|
OpenSSL.BN_mul(abinv, self.a, self.binv, self.ctx)
|
||||||
|
OpenSSL.EC_POINT_mul(self.group, temp, 0, self.Q, abinv, 0)
|
||||||
|
OpenSSL.EC_POINT_add(self.group, self.F, self.F, temp, 0)
|
||||||
|
|
||||||
|
# ... + c*G
|
||||||
|
OpenSSL.EC_POINT_mul(self.group, temp, 0, self.G, self.c, 0)
|
||||||
|
OpenSSL.EC_POINT_add(self.group, self.F, self.F, temp, 0)
|
||||||
|
|
||||||
|
# F = (x0, y0)
|
||||||
|
x0 = OpenSSL.BN_new()
|
||||||
|
y0 = OpenSSL.BN_new()
|
||||||
|
OpenSSL.EC_POINT_get_affine_coordinates_GFp(self.group, self.F, x0, y0,
|
||||||
|
self.ctx)
|
||||||
|
self.r = x0
|
||||||
|
|
||||||
|
# Requester: Blinding (m' = br(m) + a)
|
||||||
|
self.m = OpenSSL.BN_new()
|
||||||
|
OpenSSL.BN_bin2bn(msg, len(msg), self.m)
|
||||||
|
|
||||||
|
self.m_ = OpenSSL.BN_new()
|
||||||
|
OpenSSL.BN_mod_mul(self.m_, self.b, self.r, self.n, self.ctx)
|
||||||
|
OpenSSL.BN_mod_mul(self.m_, self.m_, self.m, self.n, self.ctx)
|
||||||
|
OpenSSL.BN_mod_add(self.m_, self.m_, self.a, self.n, self.ctx)
|
||||||
|
|
||||||
|
def blind_sign(self):
|
||||||
|
"""
|
||||||
|
Signer blind-signs the request
|
||||||
|
"""
|
||||||
|
self.s_ = OpenSSL.BN_new()
|
||||||
|
OpenSSL.BN_mod_mul(self.s_, self.keypair[0], self.m_, self.n, self.ctx)
|
||||||
|
OpenSSL.BN_mod_add(self.s_, self.s_, self.k, self.n, self.ctx)
|
||||||
|
|
||||||
|
def unblind(self):
|
||||||
|
"""
|
||||||
|
Requester unblinds the signature
|
||||||
|
"""
|
||||||
|
s = OpenSSL.BN_new()
|
||||||
|
OpenSSL.BN_mod_mul(s, self.binv, self.s_, self.n, self.ctx)
|
||||||
|
OpenSSL.BN_mod_add(s, s, self.c, self.n, self.ctx)
|
||||||
|
self.signature = (s, self.F)
|
||||||
|
|
||||||
|
def verify(self):
|
||||||
|
"""
|
||||||
|
Verify signature with certifier's pubkey
|
||||||
|
"""
|
||||||
|
lhs = OpenSSL.EC_POINT_new(self.group)
|
||||||
|
rhs = OpenSSL.EC_POINT_new(self.group)
|
||||||
|
|
||||||
|
OpenSSL.EC_POINT_mul(self.group, lhs, self.signature[0], 0, 0, 0)
|
||||||
|
OpenSSL.EC_POINT_mul(self.group, rhs, 0, self.Q, self.m, 0)
|
||||||
|
OpenSSL.EC_POINT_mul(self.group, rhs, 0, rhs, self.r, 0)
|
||||||
|
OpenSSL.EC_POINT_add(self.group, rhs, rhs, self.F, self.ctx)
|
||||||
|
|
||||||
|
retval = OpenSSL.EC_POINT_cmp(self.group, lhs, rhs, self.ctx)
|
||||||
|
if retval == -1:
|
||||||
|
raise RuntimeError("EC_POINT_cmp returned an error")
|
||||||
|
else:
|
||||||
|
return retval == 0
|
|
@ -4,7 +4,7 @@
|
||||||
# Copyright (C) 2011 Yann GUIBET <yannguibet@gmail.com>
|
# Copyright (C) 2011 Yann GUIBET <yannguibet@gmail.com>
|
||||||
# See LICENSE for details.
|
# See LICENSE for details.
|
||||||
|
|
||||||
from pyelliptic.openssl import OpenSSL
|
from openssl import OpenSSL
|
||||||
|
|
||||||
|
|
||||||
# For python3
|
# For python3
|
||||||
|
|
|
@ -19,7 +19,9 @@ class CipherName:
|
||||||
self._blocksize = blocksize
|
self._blocksize = blocksize
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Cipher : " + self._name + " | Blocksize : " + str(self._blocksize) + " | Fonction pointer : " + str(self._pointer)
|
return "Cipher : " + self._name + \
|
||||||
|
" | Blocksize : " + str(self._blocksize) + \
|
||||||
|
" | Function pointer : " + str(self._pointer)
|
||||||
|
|
||||||
def get_pointer(self):
|
def get_pointer(self):
|
||||||
return self._pointer()
|
return self._pointer()
|
||||||
|
@ -36,7 +38,7 @@ def get_version(library):
|
||||||
hexversion = None
|
hexversion = None
|
||||||
cflags = None
|
cflags = None
|
||||||
try:
|
try:
|
||||||
#OpenSSL 1.1
|
# OpenSSL 1.1
|
||||||
OPENSSL_VERSION = 0
|
OPENSSL_VERSION = 0
|
||||||
OPENSSL_CFLAGS = 1
|
OPENSSL_CFLAGS = 1
|
||||||
library.OpenSSL_version.argtypes = [ctypes.c_int]
|
library.OpenSSL_version.argtypes = [ctypes.c_int]
|
||||||
|
@ -47,7 +49,7 @@ def get_version(library):
|
||||||
hexversion = library.OpenSSL_version_num()
|
hexversion = library.OpenSSL_version_num()
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
try:
|
try:
|
||||||
#OpenSSL 1.0
|
# OpenSSL 1.0
|
||||||
SSLEAY_VERSION = 0
|
SSLEAY_VERSION = 0
|
||||||
SSLEAY_CFLAGS = 2
|
SSLEAY_CFLAGS = 2
|
||||||
library.SSLeay.restype = ctypes.c_long
|
library.SSLeay.restype = ctypes.c_long
|
||||||
|
@ -57,7 +59,7 @@ def get_version(library):
|
||||||
cflags = library.SSLeay_version(SSLEAY_CFLAGS)
|
cflags = library.SSLeay_version(SSLEAY_CFLAGS)
|
||||||
hexversion = library.SSLeay()
|
hexversion = library.SSLeay()
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
#raise NotImplementedError('Cannot determine version of this OpenSSL library.')
|
# raise NotImplementedError('Cannot determine version of this OpenSSL library.')
|
||||||
pass
|
pass
|
||||||
return (version, hexversion, cflags)
|
return (version, hexversion, cflags)
|
||||||
|
|
||||||
|
@ -130,7 +132,11 @@ class _OpenSSL:
|
||||||
|
|
||||||
self.EC_POINT_get_affine_coordinates_GFp = self._lib.EC_POINT_get_affine_coordinates_GFp
|
self.EC_POINT_get_affine_coordinates_GFp = self._lib.EC_POINT_get_affine_coordinates_GFp
|
||||||
self.EC_POINT_get_affine_coordinates_GFp.restype = ctypes.c_int
|
self.EC_POINT_get_affine_coordinates_GFp.restype = ctypes.c_int
|
||||||
self.EC_POINT_get_affine_coordinates_GFp.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
|
self.EC_POINT_get_affine_coordinates_GFp.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
self.EC_KEY_set_private_key = self._lib.EC_KEY_set_private_key
|
self.EC_KEY_set_private_key = self._lib.EC_KEY_set_private_key
|
||||||
self.EC_KEY_set_private_key.restype = ctypes.c_int
|
self.EC_KEY_set_private_key.restype = ctypes.c_int
|
||||||
|
@ -144,11 +150,16 @@ class _OpenSSL:
|
||||||
|
|
||||||
self.EC_KEY_set_group = self._lib.EC_KEY_set_group
|
self.EC_KEY_set_group = self._lib.EC_KEY_set_group
|
||||||
self.EC_KEY_set_group.restype = ctypes.c_int
|
self.EC_KEY_set_group.restype = ctypes.c_int
|
||||||
self.EC_KEY_set_group.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
|
self.EC_KEY_set_group.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
self.EC_POINT_set_affine_coordinates_GFp = self._lib.EC_POINT_set_affine_coordinates_GFp
|
self.EC_POINT_set_affine_coordinates_GFp = self._lib.EC_POINT_set_affine_coordinates_GFp
|
||||||
self.EC_POINT_set_affine_coordinates_GFp.restype = ctypes.c_int
|
self.EC_POINT_set_affine_coordinates_GFp.restype = ctypes.c_int
|
||||||
self.EC_POINT_set_affine_coordinates_GFp.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
|
self.EC_POINT_set_affine_coordinates_GFp.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
self.EC_POINT_new = self._lib.EC_POINT_new
|
self.EC_POINT_new = self._lib.EC_POINT_new
|
||||||
self.EC_POINT_new.restype = ctypes.c_void_p
|
self.EC_POINT_new.restype = ctypes.c_void_p
|
||||||
|
@ -164,7 +175,11 @@ class _OpenSSL:
|
||||||
|
|
||||||
self.EC_POINT_mul = self._lib.EC_POINT_mul
|
self.EC_POINT_mul = self._lib.EC_POINT_mul
|
||||||
self.EC_POINT_mul.restype = None
|
self.EC_POINT_mul.restype = None
|
||||||
self.EC_POINT_mul.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
|
self.EC_POINT_mul.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
self.EC_KEY_set_private_key = self._lib.EC_KEY_set_private_key
|
self.EC_KEY_set_private_key = self._lib.EC_KEY_set_private_key
|
||||||
self.EC_KEY_set_private_key.restype = ctypes.c_int
|
self.EC_KEY_set_private_key.restype = ctypes.c_int
|
||||||
|
@ -175,10 +190,11 @@ class _OpenSSL:
|
||||||
self.EC_KEY_OpenSSL = self._lib.EC_KEY_OpenSSL
|
self.EC_KEY_OpenSSL = self._lib.EC_KEY_OpenSSL
|
||||||
self._lib.EC_KEY_OpenSSL.restype = ctypes.c_void_p
|
self._lib.EC_KEY_OpenSSL.restype = ctypes.c_void_p
|
||||||
self._lib.EC_KEY_OpenSSL.argtypes = []
|
self._lib.EC_KEY_OpenSSL.argtypes = []
|
||||||
|
|
||||||
self.EC_KEY_set_method = self._lib.EC_KEY_set_method
|
self.EC_KEY_set_method = self._lib.EC_KEY_set_method
|
||||||
self._lib.EC_KEY_set_method.restype = ctypes.c_int
|
self._lib.EC_KEY_set_method.restype = ctypes.c_int
|
||||||
self._lib.EC_KEY_set_method.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
|
self._lib.EC_KEY_set_method.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
else:
|
else:
|
||||||
self.ECDH_OpenSSL = self._lib.ECDH_OpenSSL
|
self.ECDH_OpenSSL = self._lib.ECDH_OpenSSL
|
||||||
self._lib.ECDH_OpenSSL.restype = ctypes.c_void_p
|
self._lib.ECDH_OpenSSL.restype = ctypes.c_void_p
|
||||||
|
@ -186,7 +202,8 @@ class _OpenSSL:
|
||||||
|
|
||||||
self.ECDH_set_method = self._lib.ECDH_set_method
|
self.ECDH_set_method = self._lib.ECDH_set_method
|
||||||
self._lib.ECDH_set_method.restype = ctypes.c_int
|
self._lib.ECDH_set_method.restype = ctypes.c_int
|
||||||
self._lib.ECDH_set_method.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
|
self._lib.ECDH_set_method.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
self.BN_CTX_new = self._lib.BN_CTX_new
|
self.BN_CTX_new = self._lib.BN_CTX_new
|
||||||
self._lib.BN_CTX_new.restype = ctypes.c_void_p
|
self._lib.BN_CTX_new.restype = ctypes.c_void_p
|
||||||
|
@ -195,12 +212,15 @@ class _OpenSSL:
|
||||||
self.ECDH_compute_key = self._lib.ECDH_compute_key
|
self.ECDH_compute_key = self._lib.ECDH_compute_key
|
||||||
self.ECDH_compute_key.restype = ctypes.c_int
|
self.ECDH_compute_key.restype = ctypes.c_int
|
||||||
self.ECDH_compute_key.argtypes = [ctypes.c_void_p,
|
self.ECDH_compute_key.argtypes = [ctypes.c_void_p,
|
||||||
ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p]
|
ctypes.c_int,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
self.EVP_CipherInit_ex = self._lib.EVP_CipherInit_ex
|
self.EVP_CipherInit_ex = self._lib.EVP_CipherInit_ex
|
||||||
self.EVP_CipherInit_ex.restype = ctypes.c_int
|
self.EVP_CipherInit_ex.restype = ctypes.c_int
|
||||||
self.EVP_CipherInit_ex.argtypes = [ctypes.c_void_p,
|
self.EVP_CipherInit_ex.argtypes = [ctypes.c_void_p,
|
||||||
ctypes.c_void_p, ctypes.c_void_p]
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
self.EVP_CIPHER_CTX_new = self._lib.EVP_CIPHER_CTX_new
|
self.EVP_CIPHER_CTX_new = self._lib.EVP_CIPHER_CTX_new
|
||||||
self.EVP_CIPHER_CTX_new.restype = ctypes.c_void_p
|
self.EVP_CIPHER_CTX_new.restype = ctypes.c_void_p
|
||||||
|
@ -223,13 +243,13 @@ class _OpenSSL:
|
||||||
self.EVP_aes_256_cbc.restype = ctypes.c_void_p
|
self.EVP_aes_256_cbc.restype = ctypes.c_void_p
|
||||||
self.EVP_aes_256_cbc.argtypes = []
|
self.EVP_aes_256_cbc.argtypes = []
|
||||||
|
|
||||||
#self.EVP_aes_128_ctr = self._lib.EVP_aes_128_ctr
|
# self.EVP_aes_128_ctr = self._lib.EVP_aes_128_ctr
|
||||||
#self.EVP_aes_128_ctr.restype = ctypes.c_void_p
|
# self.EVP_aes_128_ctr.restype = ctypes.c_void_p
|
||||||
#self.EVP_aes_128_ctr.argtypes = []
|
# self.EVP_aes_128_ctr.argtypes = []
|
||||||
|
|
||||||
#self.EVP_aes_256_ctr = self._lib.EVP_aes_256_ctr
|
# self.EVP_aes_256_ctr = self._lib.EVP_aes_256_ctr
|
||||||
#self.EVP_aes_256_ctr.restype = ctypes.c_void_p
|
# self.EVP_aes_256_ctr.restype = ctypes.c_void_p
|
||||||
#self.EVP_aes_256_ctr.argtypes = []
|
# self.EVP_aes_256_ctr.argtypes = []
|
||||||
|
|
||||||
self.EVP_aes_128_ofb = self._lib.EVP_aes_128_ofb
|
self.EVP_aes_128_ofb = self._lib.EVP_aes_128_ofb
|
||||||
self.EVP_aes_128_ofb.restype = ctypes.c_void_p
|
self.EVP_aes_128_ofb.restype = ctypes.c_void_p
|
||||||
|
@ -250,7 +270,7 @@ class _OpenSSL:
|
||||||
self.EVP_rc4 = self._lib.EVP_rc4
|
self.EVP_rc4 = self._lib.EVP_rc4
|
||||||
self.EVP_rc4.restype = ctypes.c_void_p
|
self.EVP_rc4.restype = ctypes.c_void_p
|
||||||
self.EVP_rc4.argtypes = []
|
self.EVP_rc4.argtypes = []
|
||||||
|
|
||||||
if self._hexversion >= 0x10100000 and not self._libreSSL:
|
if self._hexversion >= 0x10100000 and not self._libreSSL:
|
||||||
self.EVP_CIPHER_CTX_reset = self._lib.EVP_CIPHER_CTX_reset
|
self.EVP_CIPHER_CTX_reset = self._lib.EVP_CIPHER_CTX_reset
|
||||||
self.EVP_CIPHER_CTX_reset.restype = ctypes.c_int
|
self.EVP_CIPHER_CTX_reset.restype = ctypes.c_int
|
||||||
|
@ -281,7 +301,7 @@ class _OpenSSL:
|
||||||
self.EVP_DigestInit_ex = self._lib.EVP_DigestInit_ex
|
self.EVP_DigestInit_ex = self._lib.EVP_DigestInit_ex
|
||||||
self.EVP_DigestInit_ex.restype = ctypes.c_int
|
self.EVP_DigestInit_ex.restype = ctypes.c_int
|
||||||
self._lib.EVP_DigestInit_ex.argtypes = 3 * [ctypes.c_void_p]
|
self._lib.EVP_DigestInit_ex.argtypes = 3 * [ctypes.c_void_p]
|
||||||
|
|
||||||
self.EVP_DigestUpdate = self._lib.EVP_DigestUpdate
|
self.EVP_DigestUpdate = self._lib.EVP_DigestUpdate
|
||||||
self.EVP_DigestUpdate.restype = ctypes.c_int
|
self.EVP_DigestUpdate.restype = ctypes.c_int
|
||||||
self.EVP_DigestUpdate.argtypes = [ctypes.c_void_p,
|
self.EVP_DigestUpdate.argtypes = [ctypes.c_void_p,
|
||||||
|
@ -296,7 +316,7 @@ class _OpenSSL:
|
||||||
self.EVP_DigestFinal_ex.restype = ctypes.c_int
|
self.EVP_DigestFinal_ex.restype = ctypes.c_int
|
||||||
self.EVP_DigestFinal_ex.argtypes = [ctypes.c_void_p,
|
self.EVP_DigestFinal_ex.argtypes = [ctypes.c_void_p,
|
||||||
ctypes.c_void_p, ctypes.c_void_p]
|
ctypes.c_void_p, ctypes.c_void_p]
|
||||||
|
|
||||||
self.ECDSA_sign = self._lib.ECDSA_sign
|
self.ECDSA_sign = self._lib.ECDSA_sign
|
||||||
self.ECDSA_sign.restype = ctypes.c_int
|
self.ECDSA_sign.restype = ctypes.c_int
|
||||||
self.ECDSA_sign.argtypes = [ctypes.c_int, ctypes.c_void_p,
|
self.ECDSA_sign.argtypes = [ctypes.c_int, ctypes.c_void_p,
|
||||||
|
@ -311,7 +331,7 @@ class _OpenSSL:
|
||||||
self.EVP_MD_CTX_new = self._lib.EVP_MD_CTX_new
|
self.EVP_MD_CTX_new = self._lib.EVP_MD_CTX_new
|
||||||
self.EVP_MD_CTX_new.restype = ctypes.c_void_p
|
self.EVP_MD_CTX_new.restype = ctypes.c_void_p
|
||||||
self.EVP_MD_CTX_new.argtypes = []
|
self.EVP_MD_CTX_new.argtypes = []
|
||||||
|
|
||||||
self.EVP_MD_CTX_reset = self._lib.EVP_MD_CTX_reset
|
self.EVP_MD_CTX_reset = self._lib.EVP_MD_CTX_reset
|
||||||
self.EVP_MD_CTX_reset.restype = None
|
self.EVP_MD_CTX_reset.restype = None
|
||||||
self.EVP_MD_CTX_reset.argtypes = [ctypes.c_void_p]
|
self.EVP_MD_CTX_reset.argtypes = [ctypes.c_void_p]
|
||||||
|
@ -329,11 +349,11 @@ class _OpenSSL:
|
||||||
self.EVP_MD_CTX_create = self._lib.EVP_MD_CTX_create
|
self.EVP_MD_CTX_create = self._lib.EVP_MD_CTX_create
|
||||||
self.EVP_MD_CTX_create.restype = ctypes.c_void_p
|
self.EVP_MD_CTX_create.restype = ctypes.c_void_p
|
||||||
self.EVP_MD_CTX_create.argtypes = []
|
self.EVP_MD_CTX_create.argtypes = []
|
||||||
|
|
||||||
self.EVP_MD_CTX_init = self._lib.EVP_MD_CTX_init
|
self.EVP_MD_CTX_init = self._lib.EVP_MD_CTX_init
|
||||||
self.EVP_MD_CTX_init.restype = None
|
self.EVP_MD_CTX_init.restype = None
|
||||||
self.EVP_MD_CTX_init.argtypes = [ctypes.c_void_p]
|
self.EVP_MD_CTX_init.argtypes = [ctypes.c_void_p]
|
||||||
|
|
||||||
self.EVP_MD_CTX_destroy = self._lib.EVP_MD_CTX_destroy
|
self.EVP_MD_CTX_destroy = self._lib.EVP_MD_CTX_destroy
|
||||||
self.EVP_MD_CTX_destroy.restype = None
|
self.EVP_MD_CTX_destroy.restype = None
|
||||||
self.EVP_MD_CTX_destroy.argtypes = [ctypes.c_void_p]
|
self.EVP_MD_CTX_destroy.argtypes = [ctypes.c_void_p]
|
||||||
|
@ -370,13 +390,131 @@ class _OpenSSL:
|
||||||
except:
|
except:
|
||||||
# The above is not compatible with all versions of OSX.
|
# The above is not compatible with all versions of OSX.
|
||||||
self.PKCS5_PBKDF2_HMAC = self._lib.PKCS5_PBKDF2_HMAC_SHA1
|
self.PKCS5_PBKDF2_HMAC = self._lib.PKCS5_PBKDF2_HMAC_SHA1
|
||||||
|
|
||||||
self.PKCS5_PBKDF2_HMAC.restype = ctypes.c_int
|
self.PKCS5_PBKDF2_HMAC.restype = ctypes.c_int
|
||||||
self.PKCS5_PBKDF2_HMAC.argtypes = [ctypes.c_void_p, ctypes.c_int,
|
self.PKCS5_PBKDF2_HMAC.argtypes = [ctypes.c_void_p, ctypes.c_int,
|
||||||
ctypes.c_void_p, ctypes.c_int,
|
ctypes.c_void_p, ctypes.c_int,
|
||||||
ctypes.c_int, ctypes.c_void_p,
|
ctypes.c_int, ctypes.c_void_p,
|
||||||
ctypes.c_int, ctypes.c_void_p]
|
ctypes.c_int, ctypes.c_void_p]
|
||||||
|
|
||||||
|
# Blind signature requirements
|
||||||
|
self.BN_CTX_new = self._lib.BN_CTX_new
|
||||||
|
self.BN_CTX_new.restype = ctypes.c_void_p
|
||||||
|
self.BN_CTX_new.argtypes = []
|
||||||
|
|
||||||
|
self.BN_dup = self._lib.BN_dup
|
||||||
|
self.BN_dup.restype = ctypes.c_void_p
|
||||||
|
self.BN_dup.argtypes = [ctypes.c_void_p]
|
||||||
|
|
||||||
|
self.BN_rand = self._lib.BN_rand
|
||||||
|
self.BN_rand.restype = ctypes.c_int
|
||||||
|
self.BN_rand.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_int,
|
||||||
|
ctypes.c_int]
|
||||||
|
|
||||||
|
self.BN_set_word = self._lib.BN_set_word
|
||||||
|
self.BN_set_word.restype = ctypes.c_int
|
||||||
|
self.BN_set_word.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_ulong]
|
||||||
|
|
||||||
|
self.BN_mul = self._lib.BN_mul
|
||||||
|
self.BN_mul.restype = ctypes.c_int
|
||||||
|
self.BN_mul.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
|
self.BN_mod_add = self._lib.BN_mod_add
|
||||||
|
self.BN_mod_add.restype = ctypes.c_int
|
||||||
|
self.BN_mod_add.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
|
self.BN_mod_inverse = self._lib.BN_mod_inverse
|
||||||
|
self.BN_mod_inverse.restype = ctypes.c_void_p
|
||||||
|
self.BN_mod_inverse.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
|
self.BN_mod_mul = self._lib.BN_mod_mul
|
||||||
|
self.BN_mod_mul.restype = ctypes.c_int
|
||||||
|
self.BN_mod_mul.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
|
self.BN_lshift = self._lib.BN_lshift
|
||||||
|
self.BN_lshift.restype = ctypes.c_int
|
||||||
|
self.BN_lshift.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_int]
|
||||||
|
|
||||||
|
self.BN_sub_word = self._lib.BN_sub_word
|
||||||
|
self.BN_sub_word.restype = ctypes.c_int
|
||||||
|
self.BN_sub_word.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_ulong]
|
||||||
|
|
||||||
|
self.BN_cmp = self._lib.BN_cmp
|
||||||
|
self.BN_cmp.restype = ctypes.c_int
|
||||||
|
self.BN_cmp.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
|
self.BN_bn2dec = self._lib.BN_bn2dec
|
||||||
|
self.BN_bn2dec.restype = ctypes.c_char_p
|
||||||
|
self.BN_bn2dec.argtypes = [ctypes.c_void_p]
|
||||||
|
|
||||||
|
self.BN_CTX_free = self._lib.BN_CTX_free
|
||||||
|
self.BN_CTX_free.argtypes = [ctypes.c_void_p]
|
||||||
|
|
||||||
|
self.EC_GROUP_new_by_curve_name = self._lib.EC_GROUP_new_by_curve_name
|
||||||
|
self.EC_GROUP_new_by_curve_name.restype = ctypes.c_void_p
|
||||||
|
self.EC_GROUP_new_by_curve_name.argtypes = [ctypes.c_int]
|
||||||
|
|
||||||
|
self.EC_GROUP_get_order = self._lib.EC_GROUP_get_order
|
||||||
|
self.EC_GROUP_get_order.restype = ctypes.c_int
|
||||||
|
self.EC_GROUP_get_order.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
|
self.EC_GROUP_get_cofactor = self._lib.EC_GROUP_get_cofactor
|
||||||
|
self.EC_GROUP_get_cofactor.restype = ctypes.c_int
|
||||||
|
self.EC_GROUP_get_cofactor.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
|
self.EC_GROUP_get0_generator = self._lib.EC_GROUP_get0_generator
|
||||||
|
self.EC_GROUP_get0_generator.restype = ctypes.c_void_p
|
||||||
|
self.EC_GROUP_get0_generator.argtypes = [ctypes.c_void_p]
|
||||||
|
|
||||||
|
self.EC_POINT_copy = self._lib.EC_POINT_copy
|
||||||
|
self.EC_POINT_copy.restype = ctypes.c_int
|
||||||
|
self.EC_POINT_copy.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
|
self.EC_POINT_add = self._lib.EC_POINT_add
|
||||||
|
self.EC_POINT_add.restype = ctypes.c_int
|
||||||
|
self.EC_POINT_add.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
|
self.EC_POINT_cmp = self._lib.EC_POINT_cmp
|
||||||
|
self.EC_POINT_cmp.restype = ctypes.c_int
|
||||||
|
self.EC_POINT_cmp.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
|
self.EC_POINT_set_to_infinity = self._lib.EC_POINT_set_to_infinity
|
||||||
|
self.EC_POINT_set_to_infinity.restype = ctypes.c_int
|
||||||
|
self.EC_POINT_set_to_infinity.argtypes = [ctypes.c_void_p,
|
||||||
|
ctypes.c_void_p]
|
||||||
|
|
||||||
self._set_ciphers()
|
self._set_ciphers()
|
||||||
self._set_curves()
|
self._set_curves()
|
||||||
|
|
||||||
|
@ -388,11 +526,11 @@ class _OpenSSL:
|
||||||
'aes-256-cfb': CipherName('aes-256-cfb', self.EVP_aes_256_cfb128, 16),
|
'aes-256-cfb': CipherName('aes-256-cfb', self.EVP_aes_256_cfb128, 16),
|
||||||
'aes-128-ofb': CipherName('aes-128-ofb', self._lib.EVP_aes_128_ofb, 16),
|
'aes-128-ofb': CipherName('aes-128-ofb', self._lib.EVP_aes_128_ofb, 16),
|
||||||
'aes-256-ofb': CipherName('aes-256-ofb', self._lib.EVP_aes_256_ofb, 16),
|
'aes-256-ofb': CipherName('aes-256-ofb', self._lib.EVP_aes_256_ofb, 16),
|
||||||
#'aes-128-ctr': CipherName('aes-128-ctr', self._lib.EVP_aes_128_ctr, 16),
|
# 'aes-128-ctr': CipherName('aes-128-ctr', self._lib.EVP_aes_128_ctr, 16),
|
||||||
#'aes-256-ctr': CipherName('aes-256-ctr', self._lib.EVP_aes_256_ctr, 16),
|
# 'aes-256-ctr': CipherName('aes-256-ctr', self._lib.EVP_aes_256_ctr, 16),
|
||||||
'bf-cfb': CipherName('bf-cfb', self.EVP_bf_cfb64, 8),
|
'bf-cfb': CipherName('bf-cfb', self.EVP_bf_cfb64, 8),
|
||||||
'bf-cbc': CipherName('bf-cbc', self.EVP_bf_cbc, 8),
|
'bf-cbc': CipherName('bf-cbc', self.EVP_bf_cbc, 8),
|
||||||
'rc4': CipherName('rc4', self.EVP_rc4, 128), # 128 is the initialisation size not block size
|
'rc4': CipherName('rc4', self.EVP_rc4, 128), # 128 is the initialisation size not block size
|
||||||
}
|
}
|
||||||
|
|
||||||
def _set_curves(self):
|
def _set_curves(self):
|
||||||
|
@ -470,11 +608,11 @@ class _OpenSSL:
|
||||||
OpenSSL random function
|
OpenSSL random function
|
||||||
"""
|
"""
|
||||||
buffer = self.malloc(0, size)
|
buffer = self.malloc(0, size)
|
||||||
# This pyelliptic library, by default, didn't check the return value of RAND_bytes. It is
|
# This pyelliptic library, by default, didn't check the return value of RAND_bytes. It is
|
||||||
# evidently possible that it returned an error and not-actually-random data. However, in
|
# evidently possible that it returned an error and not-actually-random data. However, in
|
||||||
# tests on various operating systems, while generating hundreds of gigabytes of random
|
# tests on various operating systems, while generating hundreds of gigabytes of random
|
||||||
# strings of various sizes I could not get an error to occur. Also Bitcoin doesn't check
|
# strings of various sizes I could not get an error to occur. Also Bitcoin doesn't check
|
||||||
# the return value of RAND_bytes either.
|
# the return value of RAND_bytes either.
|
||||||
# Fixed in Bitmessage version 0.4.2 (in source code on 2013-10-13)
|
# Fixed in Bitmessage version 0.4.2 (in source code on 2013-10-13)
|
||||||
while self.RAND_bytes(buffer, size) != 1:
|
while self.RAND_bytes(buffer, size) != 1:
|
||||||
import time
|
import time
|
||||||
|
@ -494,22 +632,23 @@ class _OpenSSL:
|
||||||
buffer = self.create_string_buffer(size)
|
buffer = self.create_string_buffer(size)
|
||||||
return buffer
|
return buffer
|
||||||
|
|
||||||
|
|
||||||
def loadOpenSSL():
|
def loadOpenSSL():
|
||||||
global OpenSSL
|
global OpenSSL
|
||||||
from os import path, environ
|
from os import path, environ
|
||||||
from ctypes.util import find_library
|
from ctypes.util import find_library
|
||||||
|
|
||||||
libdir = []
|
libdir = []
|
||||||
if getattr(sys,'frozen', None):
|
if getattr(sys, 'frozen', None):
|
||||||
if 'darwin' in sys.platform:
|
if 'darwin' in sys.platform:
|
||||||
libdir.extend([
|
libdir.extend([
|
||||||
path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.dylib'),
|
path.join(environ['RESOURCEPATH'], '..', 'Frameworks', 'libcrypto.dylib'),
|
||||||
path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.1.1.0.dylib'),
|
path.join(environ['RESOURCEPATH'], '..', 'Frameworks', 'libcrypto.1.1.0.dylib'),
|
||||||
path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.1.0.2.dylib'),
|
path.join(environ['RESOURCEPATH'], '..', 'Frameworks', 'libcrypto.1.0.2.dylib'),
|
||||||
path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.1.0.1.dylib'),
|
path.join(environ['RESOURCEPATH'], '..', 'Frameworks', 'libcrypto.1.0.1.dylib'),
|
||||||
path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.1.0.0.dylib'),
|
path.join(environ['RESOURCEPATH'], '..', 'Frameworks', 'libcrypto.1.0.0.dylib'),
|
||||||
path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.0.9.8.dylib'),
|
path.join(environ['RESOURCEPATH'], '..', 'Frameworks', 'libcrypto.0.9.8.dylib'),
|
||||||
])
|
])
|
||||||
elif 'win32' in sys.platform or 'win64' in sys.platform:
|
elif 'win32' in sys.platform or 'win64' in sys.platform:
|
||||||
libdir.append(path.join(sys._MEIPASS, 'libeay32.dll'))
|
libdir.append(path.join(sys._MEIPASS, 'libeay32.dll'))
|
||||||
else:
|
else:
|
||||||
|
@ -548,4 +687,5 @@ def loadOpenSSL():
|
||||||
pass
|
pass
|
||||||
raise Exception("Couldn't find and load the OpenSSL library. You must install it.")
|
raise Exception("Couldn't find and load the OpenSSL library. You must install it.")
|
||||||
|
|
||||||
|
|
||||||
loadOpenSSL()
|
loadOpenSSL()
|
||||||
|
|
22
src/tests/test_blindsig.py
Normal file
22
src/tests/test_blindsig.py
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
"""
|
||||||
|
Test for ECC blind signatures
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from src.pyelliptic.eccblind import ECCBlind
|
||||||
|
|
||||||
|
|
||||||
|
class TestBlindSig(unittest.TestCase):
|
||||||
|
"""
|
||||||
|
Test case for ECC blind signature
|
||||||
|
"""
|
||||||
|
def test_blind_sig(self):
|
||||||
|
"""Test full sequence using a random certifier key and a random message"""
|
||||||
|
blind_sig = ECCBlind()
|
||||||
|
blind_sig.signer_init()
|
||||||
|
msg = os.urandom(64)
|
||||||
|
blind_sig.create_signing_request(msg)
|
||||||
|
blind_sig.blind_sign()
|
||||||
|
blind_sig.unblind()
|
||||||
|
self.assertTrue(blind_sig.verify())
|
Reference in New Issue
Block a user