Skip to content
This repository has been archived by the owner on Sep 10, 2019. It is now read-only.

Commit

Permalink
Merge 598254c into fdfbc56
Browse files Browse the repository at this point in the history
  • Loading branch information
jseagrave21 committed Mar 12, 2019
2 parents fdfbc56 + 598254c commit 1f31a11
Show file tree
Hide file tree
Showing 16 changed files with 235 additions and 122 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Expand Up @@ -24,9 +24,9 @@ script:
- pycodestyle neocore tests

# now test the upstream neo-python dev branch with the current neocore code
- git clone https://github.com/CityOfZion/neo-python.git
- git clone https://github.com/jseagrave21/neo-python.git
- cd neo-python
- git checkout origin/development -b development
- git checkout origin/support-#888 -b support-#888
- pip install -e .
- yes | pip uninstall neocore neo-boa
- pip install git+https://github.com/CityOfZion/neo-boa@development
Expand Down
11 changes: 5 additions & 6 deletions neocore/Cryptography/Crypto.py
@@ -1,6 +1,5 @@
import bitcoin
from ecdsa import NIST256p, VerifyingKey
from logzero import logger
from .Helper import *
from neocore.UInt160 import UInt160
from .ECCurve import EllipticCurve
Expand Down Expand Up @@ -108,7 +107,7 @@ def Sign(message, private_key):
Sign the message with the given private key.
Args:
message (str): message to be signed
message (hexstr): message to be signed
private_key (str): 32 byte key as a double digit hex string (e.g. having a length of 64)
Returns:
bytearray: the signature of the message.
Expand All @@ -131,7 +130,7 @@ def VerifySignature(message, signature, public_key, unhex=True):
Verify the integrity of the message.
Args:
message (str): the message to verify.
message (hexstr or str): the message to verify.
signature (bytearray): the signature belonging to the message.
public_key (ECPoint|bytes): the public key to use for verifying the signature. If `public_key` is of type bytes then it should be raw bytes (i.e. b'\xAA\xBB').
unhex (bool): whether the message should be unhexlified before verifying
Expand All @@ -149,8 +148,8 @@ def VerifySignature(message, signature, public_key, unhex=True):
if unhex:
try:
message = binascii.unhexlify(message)
except Exception as e:
logger.error("could not get m: %s" % e)
except binascii.Error:
pass
elif isinstance(message, str):
message = message.encode('utf-8')

Expand All @@ -162,7 +161,7 @@ def VerifySignature(message, signature, public_key, unhex=True):
vk = VerifyingKey.from_string(public_key, curve=NIST256p, hashfunc=hashlib.sha256)
res = vk.verify(signature, message, hashfunc=hashlib.sha256)
return res
except Exception as e:
except Exception:
pass

return False
Expand Down
93 changes: 72 additions & 21 deletions neocore/Cryptography/ECCurve.py
Expand Up @@ -8,7 +8,6 @@
import random
import binascii
from mpmath.libmp import bitcount as _bitlength
from logzero import logger

modpow = pow

Expand Down Expand Up @@ -49,8 +48,18 @@ def randbytes(n):


def next_random_integer(size_in_bits):
"""
Args:
size_in_bits (int): used to specify the size in bits of the random integer
Returns:
int: random integer
Raises:
ValueError: if the specified size in bits is < 0
"""
if size_in_bits < 0:
raise Exception('size in bits must be greater than zero')
raise ValueError(f'size in bits ({size_in_bits}) must be greater than zero')
if size_in_bits == 0:
return 0

Expand All @@ -65,9 +74,17 @@ def next_random_integer(size_in_bits):


def _lucas_sequence(n, P, Q, k):
"""Return the modular Lucas sequence (U_k, V_k, Q_k).
Given a Lucas sequence defined by P, Q, returns the kth values for
U and V, along with Q^k, all modulo n.
"""
Returns:
The modular Lucas sequence (U_k, V_k, Q_k).
Given a Lucas sequence defined by P, Q, returns the kth values for
U and V, along with Q^k, all modulo n.
Raises:
ValueError:
if n is < 2
if k < 0
if D == 0
"""
D = P * P - 4 * Q
if n < 2:
Expand Down Expand Up @@ -145,19 +162,22 @@ def _lucas_sequence(n, P, Q, k):


def sqrtCQ(val, CQ):
"""
Raises:
LegendaireExponentError: if modpow(val, legendreExponent, CQ) != 1
"""
if test_bit(CQ, 1):
z = modpow(val, (CQ >> 2) + 1, CQ)
zsquare = (z * z) % CQ
if (z * z) % CQ == val:
if zsquare == val:
return z
else:
return None

qMinusOne = CQ - 1
legendreExponent = qMinusOne >> 1
if modpow(val, legendreExponent, CQ) != 1:
logger.error("legendaire exponent error")
return None
raise LegendaireExponentError()

u = qMinusOne >> 2
k = (u << 1) + 1
Expand Down Expand Up @@ -185,6 +205,11 @@ def sqrtCQ(val, CQ):
return None


class LegendaireExponentError(Exception):
"""Provide user friendly feedback in case of a legendaire exponent error."""
pass


class FiniteField:
"""
FiniteField implements a value modulus a number.
Expand Down Expand Up @@ -248,7 +273,11 @@ def sqrt(self, flag):
return self.field.sqrt(self, flag)

def sqrtCQ(self, CQ):
return self.field.sqrtCQ(self, CQ)
try:
res = self.field.sqrtCQ(self, CQ)
except LegendaireExponentError:
res = None
return res

def inverse(self):
return self.field.inverse(self)
Expand Down Expand Up @@ -287,6 +316,9 @@ def neg(self, val):
def sqrt(self, val, flag):
"""
calculate the square root modulus p
Raises:
ValueError: if self.p % 8 == 1
"""
if val.iszero():
return val
Expand All @@ -300,7 +332,7 @@ def sqrt(self, val, flag):
else:
res = (4 * val) ** ((self.p - 5) / 8) * 2 * val
else:
raise Exception("modsqrt non supported for (p%8)==1")
raise ValueError("modsqrt non supported for (p%8)==1")

if res.value % 2 == flag:
return res
Expand Down Expand Up @@ -570,9 +602,17 @@ def decompress(self, x, flag):
return self.point(x, ysquare.sqrt(flag))

def decode_from_reader(self, reader):
"""
Raises:
NotImplementedError: if an unsupported point encoding is used
TypeError: if unexpected encoding is read
"""
try:
f = reader.ReadByte()
except ValueError:
return self.Infinity

f = reader.ReadByte()

f = int.from_bytes(f, "little")
if f == 0:
return self.Infinity

Expand All @@ -589,10 +629,15 @@ def decode_from_reader(self, reader):
elif f == 4 or f == 6 or f == 7:
raise NotImplementedError()

raise Exception("Invalid point incoding: %s " % f)
raise TypeError(f"Invalid point encoding: {f}")

def decode_from_hex(self, hex_str, unhex=True):

"""
Raises:
ValueError: if the hex_str is an incorrect length for encoding or compressed encoding
NotImplementedError: if an unsupported point encoding is used
TypeError: if unexpected encoding is read
"""
ba = None
if unhex:
ba = bytearray(binascii.unhexlify(hex_str))
Expand All @@ -611,7 +656,7 @@ def decode_from_hex(self, hex_str, unhex=True):
# these are compressed
if f == 2 or f == 3:
if len(ba) != expected_byte_len + 1:
raise Exception("Incorrrect length for encoding")
raise ValueError("Incorrect length for encoding")
yTilde = f & 1
data = bytearray(ba[1:])
data.reverse()
Expand All @@ -623,7 +668,7 @@ def decode_from_hex(self, hex_str, unhex=True):
elif f == 4:

if len(ba) != (2 * expected_byte_len) + 1:
raise Exception("Incorrect length for compressed encoding")
raise ValueError("Incorrect length for compressed encoding")

x_data = bytearray(ba[1:1 + expected_byte_len])
x_data.reverse()
Expand All @@ -643,7 +688,7 @@ def decode_from_hex(self, hex_str, unhex=True):
raise NotImplementedError()

else:
raise Exception("Invalid point incoding: %s " % f)
raise TypeError(f"Invalid point encoding: {f}")

def decompress_from_curve(self, x, flag):
"""
Expand All @@ -656,7 +701,10 @@ def decompress_from_curve(self, x, flag):

ysquare = x ** 3 + self.a * x + self.b

ysquare_root = sqrtCQ(ysquare.value, cq)
try:
ysquare_root = sqrtCQ(ysquare.value, cq)
except LegendaireExponentError:
ysquare_root = None

bit0 = 0
if ysquare_root % 2 is not 0:
Expand Down Expand Up @@ -785,8 +833,8 @@ def crack2(self, r, s1, s2, m1, m2):
x2 = self.crack1(r, s2, m2, secret)

if x1 != x2:
logger.info("x1= %s" % x1)
logger.info("x2= %s" % x2)
print("x1= %s" % x1)
print("x2= %s" % x2)

return (secret, x1)

Expand Down Expand Up @@ -817,6 +865,9 @@ def secp256r1():
def decode_secp256r1(str, unhex=True, check_on_curve=True):
"""
decode a public key on the secp256r1 curve
Raises:
ValueError: if input `str` could not be decoded
"""

GFp = FiniteField(int("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", 16))
Expand All @@ -829,7 +880,7 @@ def decode_secp256r1(str, unhex=True, check_on_curve=True):
if point.isoncurve():
return ECDSA(GFp, point, int("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", 16))
else:
raise Exception("Could not decode string")
raise ValueError(f"Could not decode string: {str}")

return ECDSA(GFp, point, int("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", 16))

Expand Down
6 changes: 3 additions & 3 deletions neocore/Cryptography/Helper.py
Expand Up @@ -146,11 +146,11 @@ def base256_encode(n, minwidth=0): # int/long to byte array
n (int): input value.
minwidth: minimum return value length.
Raises:
ValueError: if a negative number is provided.
Returns:
bytearray:
Raises:
ValueError: if a negative number is provided for `n`.
"""
if n > 0:
arr = []
Expand Down
11 changes: 8 additions & 3 deletions neocore/Cryptography/MerkleTree.py
Expand Up @@ -76,9 +76,12 @@ def __Build(leaves):
Returns:
MerkleTreeNode: the root node.
Raises:
ValueError: if the length of `leaves` is < 1
"""
if len(leaves) < 1:
raise Exception('Leaves must have length')
raise ValueError('Leaves must have length')
if len(leaves) == 1:
return leaves[0]

Expand Down Expand Up @@ -115,9 +118,12 @@ def ComputeRoot(hashes):
Returns:
bytes: the root hash.
Raises:
ValueError: if the `hashes` array is empty
"""
if not len(hashes):
raise Exception('Hashes must have length')
raise ValueError('Hashes must have length')
if len(hashes) == 1:
return hashes[0]

Expand Down Expand Up @@ -157,7 +163,6 @@ def Trim(self, flags):
Args:
flags: "0000" for trimming, any other value for keeping the nodes.
"""
logger.info("Trimming!")
flags = bytearray(flags)
length = 1 << self.Depth - 1
while len(flags) < length:
Expand Down
4 changes: 2 additions & 2 deletions neocore/Fixed8.py
Expand Up @@ -53,12 +53,12 @@ def TryParse(value, require_positive=False):
val = None
try:
val = float(value)
except Exception as e:
except Exception:
pass
if not val:
try:
val = int(value)
except Exception as e:
except Exception:
pass
if val is not None:

Expand Down

0 comments on commit 1f31a11

Please sign in to comment.