Exemple #1
0
 def __init__(self, q, a, b, G, n):
     """"""
     if (q != int(q)) or (q < 3):
         raise ValueError("Invalid Input: q should be a positive integer")
     if (a != int(a)) or (a < 0):
         raise ValueError("Invalid Input")
     if (b != int(b)) or (b < 0):
         raise ValueError("Invalid Input")
     if rabinmiller.isPrime(q) is not True:
         raise ValueError("Invalid Input: q must be prime")
     if (q % 3) != 2:
         raise ValueError("Invalid Input: q must be congruent to 2 (mod 3)")
     if (len(G) != 2):
         raise ValueError("Invalid Input: G must be a tuple (dimension 2)")
     if (G[0] != int(G[0])) or (G[0] < 0):
         raise ValueError("Invalid Input")
     if (G[1] != int(G[1])) or (G[1] < 0):
         raise ValueError("Invalid Input")
     if (n != int(n)) or (n < 0):
         raise ValueError("Invalid Input")
     self.q = int(q)
     self.a = int(a)
     self.b = int(b)
     self.curve = {
         "p": self.q,
         "bits": self.q.bit_length(),
         "n": int(n),
         "a": self.a,
         "b": self.b,
         "G": (G[0], G[1])
     }
     # print("curve =", self.curve)
     self.G = Generator.init(G[0], G[1], curve=self.curve)
     # precalculate some constants (inverses of 3, 2, 27) in Fq
     self._3inv = pow(3, self.q - 2, self.q)
     # print("_3inv =", self._3inv)
     assert ((3 * self._3inv) % self.q) == 1
     self._cubeRtExp = _modinv(3, self.q - 1)
     # print("_cubeRtExp =", self._3inv)
     assert ((3 * self._cubeRtExp) % (self.q - 1)) == 1
     self._27inv = pow(27, self.q - 2, self.q)
     # print("_27inv =", self._27inv)
     assert ((27 * self._27inv) % self.q) == 1
     self._3a = (3 * a) % self.q
     # set up H1, H2 as two random uniform hash functions based on
     # the Carter and Wegman construction
     self.H1 = CWHashFunction(self.q)
     self.H2 = CWHashFunction(self.q)
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from ciphrtxt.keys import PrivateKey, PublicKey
from Crypto.Random import random
import time

from ecpy.curves import curve_secp256k1
from ecpy.point import Point, Generator

_C = curve_secp256k1
# _C = curve_secp384r1
# _C = curve_secp112r1
# _C = curve_bauer9

_G_Pt = Generator.init(_C['G'][0], _C['G'][1])

import sys
sys.setrecursionlimit(512)
alice = PrivateKey(name='Alice')
alice.set_metadata('phone', '555-555-1212')
print('name =', alice.name)
print('phone=', alice.get_metadata('phone'))
bob = PrivateKey()
for i in range(100):
    alice.randomize(4)
    bob.randomize(4)
    print('p= ' + str(alice))
    ex = alice.serialize_pubkey()
    print('P=', str(ex))
    print('\n')
from ecpy.point import Point, Generator
from ecpy.ecdsa import ECDSA

# version = 1.00 in fixed point
_msg_api_ver_v1 = b'M0100'
_msg_api_ver_v2 = b'M\x02\x00\x00'

_C = curve_secp256k1
# _C = curve_secp384r1
# _C = curve_secp112r1
# _C = curve_bauer9

_masksize = min(32, _C['bits'])
_maskbits = (int((_masksize / 3) + 0))

_G = Generator.init(_C['G'][0], _C['G'][1])
ECDSA.set_curve(_C)
ECDSA.set_generator(_G)
_ecdsa = ECDSA()

# convert integer to hex string
_pfmt = '%%0%dx' % (((_C['bits'] + 7) >> 3) << 1)
_mfmt = '%%0%dx' % (((_masksize + 7) >> 3) << 1)

# 256 bit message seed
_s_bytes = 32 
# 64 bit plaintext length field
_l_bytes = 8

_lfmt = '%016x'
Exemple #4
0
class NAK(object):
    n = _def_curve['n']
    G = Generator.init(_def_curve['G'][0], _def_curve['G'][1])
    ecdsa = ECDSA()
    
    def __init__(self, expire=None, pubkey=None, signature=None, privkey=None):
        self.expire = expire
        self.pubkey = pubkey
        self.signature = signature
        self.privkey = privkey
        if privkey is not None and pubkey is None:
            self.pubkey = NAK.G * privkey
        if self.pubkey is not None:
            self.pubkeyb = unhexlify(self.pubkey.compress())
        else:
            self.pubkeyb = None

    @staticmethod
    def deserialize(rawbytes):
        etime = int(hexlify(rawbytes[0:4]), 16)
        #print('time = ' + str(time.gmtime(etime)))
        Pkey = Point.decompress(hexlify(rawbytes[4:37]))
        #print('point = ' + Pkey.compress())
        sig0 = int(hexlify(rawbytes[37:69]),16)
        sig1 = int(hexlify(rawbytes[69:101]),16)
        sig = (sig0, sig1)
        #print('sig = (0x%032x, 0x%032x)' % (sig[0], sig[1]))
        #print('verifying %s' % hexlify(rawbytes[:37]))
        if not NAK.ecdsa.verify(Pkey,sig,rawbytes[:37]):
            #print('verify failed')
            return None
        return NAK(etime, Pkey, sig)

    def serialize(self):
        hexmsg = b'%08x' % self.expire
        hexmsg += self.pubkey.compress()
        if self.signature is None:
            if self.privkey is None:
                return None
            else:
                bmsg = unhexlify(hexmsg)
                self.signature = NAK.ecdsa.sign(self.privkey, bmsg)
        hexmsg += b'%064x' % self.signature[0]
        hexmsg += b'%064x' % self.signature[1]
        return unhexlify(hexmsg)

    def randomize(self, expire=None):
        self.privkey = random.randint(1,NAK.n-1)
        self.pubkey = NAK.G * self.privkey
        if expire is not None:
            self.expire = expire
        else:
            self.expire = int(time.time()) + (365*24*60*60)
        self.serialize()

    def dumpjson(self):
        exp = {}
        if self.signature is None:
            serialized = self.serialize()
            if serialized is None:
                return None
        exp['pubkey'] = self.pubkey.compress().decode()
        exp['expire'] = self.expire
        exp['signature'] = self.signature
        return json.dumps(exp)

    @staticmethod
    def loadjson(load):
        try:
            raw = json.loads(load)
            expire = raw['expire']
            pubkey = Point.decompress(raw['pubkey'])
            signature = raw['signature']
            return NAK(expire, pubkey, signature)
        except:
            return None

    def sign(self,message):
        if self.privkey is None:
            return None
        return NAK.ecdsa.sign(self.privkey, message)

    def verify(self,signature,message):
        if self.pubkey is None:
            return False
        return NAK.ecdsa.verify(self.pubkey, signature, message)

    def pubkeybin(self):
        if self.pubkeyb is not None:
            return self.pubkeyb
        if self.pubkey is not None:
            self.pubkeyb = unhexlify(self.pubkey.compress())
            return self.pubkeyb
        return None

    def __eq__(self, r):
        if self.expire != r.expire:
            return False
        if self.pubkey != r.pubkey:
            return False
        return True

    def __ne__(self, r):
        return not (self == r)

    def __gt__(self, r):
        if self.expire == r.expire:
            return self.pubkey.compress() > r.pubkey.compress()
        return self.expire > r.expire

    def __lt__(self, r):
        if self.expire == r.expire:
            return self.pubkey.compress() < r.pubkey.compress()
        return self.expire < r.expire

    def __le__(self, r):
        return not (self > r)

    def __ge__(self, r):
        return not (self < r)
    
    def __str__(self):
        return str(self.pubkey) + ' expires ' + str(time.gmtime(self.expire))
    
    def __repr__(self):
        ser = self.serialize()
        if ser is not None:
            return 'NAK.deserialize(unhexlify(%s))' % hexlify(ser)
        return 'NAK(0x%08x,Point.decompress(%s))' % (self.expire, self.pubkey.compress())
Exemple #5
0
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from Crypto.Random import random

from binascii import hexlify, unhexlify
import time
import json

from ecpy.curves import curve_secp256k1
from ecpy.point import Point, Generator
from ecpy.ecdsa import ECDSA

_def_curve = curve_secp256k1
Point.set_curve(_def_curve)
ECDSA.set_curve(_def_curve)
ECDSA.set_generator(Generator.init(_def_curve['G'][0], _def_curve['G'][1]))

class NAK(object):
    n = _def_curve['n']
    G = Generator.init(_def_curve['G'][0], _def_curve['G'][1])
    ecdsa = ECDSA()
    
    def __init__(self, expire=None, pubkey=None, signature=None, privkey=None):
        self.expire = expire
        self.pubkey = pubkey
        self.signature = signature
        self.privkey = privkey
        if privkey is not None and pubkey is None:
            self.pubkey = NAK.G * privkey
        if self.pubkey is not None:
            self.pubkeyb = unhexlify(self.pubkey.compress())
Exemple #6
0
import hashlib
import base64
import json
import sys
from binascii import hexlify, unhexlify
import nak

from ecpy.curves import curve_secp256k1
from ecpy.point import Point, Generator
from ecpy.ecdsa import ECDSA
from Crypto.Random import random
from Crypto.Cipher import AES
from Crypto.Util import Counter

Point.set_curve(curve_secp256k1)
_G = Generator.init(curve_secp256k1['G'][0], curve_secp256k1['G'][1])
ECDSA.set_generator(_G)

client_p = random.randint(1,curve_secp256k1['n']-1)
client_P = _G * client_p

client_r = random.randint(1,curve_secp256k1['n']-1)
client_R = _G * client_r

ecdsa=ECDSA()

_server = "http://indigo.bounceme.net:5000/"
_server2 = "http://coopr8.com:5000/"
_server3 = "http://ciphrtxt.com:5000/"
_status = "api/status/"
_onion = "onion/"
Exemple #7
0
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from ecpy.point import Point, Generator
import ecpy.curves as curves
from Crypto.Random import random

#_curve = curves.curve_secp112r1
#_curve = curves.curve_secp224k1
_curve = curves.curve_secp256k1
#_curve = curves.curve_secp384r1
#_curve = curves.curve_bauer9

Generator.set_curve(_curve)

if __name__ == '__main__':
    n = _curve['p']

    Gaffine = _curve['G']
    G = Generator.init(Gaffine[0], Gaffine[1])
    q = []
    for i in range(0, 10):
        nq = i
        nQ = G * nq
        print("{\"secp256k1\", \"0x%064X\", \"%s\"}," %
              (nq, nQ.compress().decode()))
    for i in range(0, 10):
        nq = random.randint(2, n - 1)
        nQ = G * nq
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from ecpy.point import Point, Generator
import ecpy.curves as curves
from Crypto.Random import random
from Crypto.Hash import RIPEMD
from hashlib import sha256
import hashlib
from binascii import hexlify, unhexlify
from base58 import b58encode, b58decode

# set up elliptic curve environment
c = curves.curve_secp256k1
Point.set_curve(c)
G = Generator(c['G'][0], c['G'][1])

#mainnet
pub_prefix = '00'
prv_prefix = '80'
#testnet
pub_prefix = '6f'
prv_prefix = 'ef'
#simtest
pub_prefix = '3f'
prv_prefix = '64'
#ctindigonet
pub_prefix = '1c'
prv_prefix = 'bb'
#ctrednet
pub_prefix = '50'
 def __init__(self, nbit, b=None, u=None, G=None, friendly=True):
     # first, find umax, umin such that p < 2**nbit, p > 2**(nbit - 1)
     # p = 36u**4 + 36u**3 + 24u**2 + 6u + 1
     # n = 36u**4 + 36u**3 + 18u**2 + 6u + 1
     limit = pow(2, nbit)
     if u is None:
         # derive u randomly based on nbit
         # coarse upper, lower guesses
         upr = int((limit / 36)**0.25)
         lwr = 0
         mid = (upr + lwr) >> 1
         # midpoint algorithm
         while ((mid != upr) or (mid != lwr)):
             mid = (upr + lwr) >> 1
             pu = _pfunc(upr)
             pl = _pfunc(lwr)
             pm = _pfunc(mid)
             # print("limit goal = %d" % (limit))
             # print("lower p(%d) = %d" % (lwr, pl))
             # print("mid p(%d) = %d" % (mid, pm))
             # print("upper p(%d) = %d" % (upr, pu))
             # print("")
             # pm should be odd, limit even. They should never meet
             assert (pm != limit)
             if pm < limit:
                 if lwr == mid:
                     break
                 lwr = mid
             else:
                 upr = mid
         umax = mid
         # repeat for limit = 2 ** (nbit-1)
         limit = pow(2, (nbit - 1))
         upr = int((limit / 36)**0.25)
         lwr = 0
         mid = (upr + lwr) >> 1
         while ((mid != upr) or (mid != lwr)):
             mid = (upr + lwr) >> 1
             pu = _pfunc(upr)
             pl = _pfunc(lwr)
             pm = _pfunc(mid)
             #pm should be odd, limit should be even. They should never meet
             assert (pm != limit)
             if pm < limit:
                 if lwr == mid:
                     break
                 lwr = mid
             else:
                 upr = mid
         umin = mid
     else:
         # u is a parameter
         umax = u
         umin = umax
     print("limit goal = %X" % (pow(2, nbit)))
     print("umax = %X, pmax = %X" % (umax, _pfunc(umax)))
     print("umin = %X, pmin = %X" % (umin, _pfunc(umin)))
     print("(%d potential u values, approx 2 ** %d)" %
           ((umax - umin) + 1, int(math.log((umax - umin) + 1, 2) + 0.5)))
     # choose u at random until valid solution, follow algorithm 1 from:
     # https://www.cryptojedi.org/papers/pfcpo.pdf
     self.u = 0
     if u is None:
         while True:
             urand = random.randint(umin, umax)
             #urand = 6518589491078791937
             p = _pfunc(urand)
             #assert p == 65000549695646603732796438742359905742825358107623003571877145026864184071783
             if isPrime(p) != True:
                 continue
             n = _nfunc(urand)
             #assert n == 65000549695646603732796438742359905742570406053903786389881062969044166799969
             if isPrime(n) != True:
                 continue
             if (p % 4) == 3:
                 if ((p * p) % 16) == 9:
                     self.u = urand
                     self.p = p
                     self.n = n
                     break
     else:
         p = _pfunc(umax)
         n = _nfunc(umax)
         self.u = umax
         self.p = p
         self.n = n
     if b is not None:
         friendly = False
     # print("u = %X (%d)" % (self.u, self.u))
     # print("p = %X (%d)" % (self.p, self.p))
     # print("n = %X (%d)" % (self.n, self.n))
     if friendly:
         # print("searching for b")
         while True:
             #select friendly parameters per Pereira et al
             #we happen to choose d as pure imaginary such that Xi is not
             c = random.randint(0, self.p)
             di = random.randint(0, self.p)
             b = pow(c, 4, self.p) - pow(di, 6, self.p)
             if b != (b % self.p):
                 continue
             if _legendre(b + 1, self.p) != 1:
                 continue
             y = _mod_sqrt(b + 1, self.p)
             # print("trying b = %X, y = %X, y**2 = %X" % (b, y, ((y * y) % p)))
             p2 = self.p * self.p
             #
             curve1 = {
                 'p': self.p,
                 'a': 0,
                 'b': b,
                 'n': self.n,
                 'bits': nbit
             }
             Generator.set_curve(curve1)
             P = Point(pow(di, 2, self.p), pow(c, 2, self.p))
             assert P.is_valid()
             Pnm1 = (self.n - 1) * P
             Ptst = Pnm1 + P
             if Ptst.is_infinite != True:
                 continue
             self.G = Generator(pow(di, 2, self.p), pow(c, 2, self.p))
             self.b = b
             Xi = pow(c, 2, p2) + pow(di, 3, p2)
             bprime = (b * _modinv(Xi, p2))
             h = (2 * self.p) - self.n
             curve2 = {
                 'p': self.p * self.p,
                 'a': 0,
                 'b': bprime,
                 'n': self.n,
                 'bits': 2 * nbit
             }
             break
     else:
         if G is None:
             if b is None:
                 b = 0
             else:
                 b = b - 1
             while True:
                 b = b + 1
                 if _legendre(b + 1, self.p) != 1:
                     # print("b = %d but %d is not quadratic residue" % (b, b+1))
                     continue
                 y = _mod_sqrt(b + 1, self.p)
                 # print("trying b = %X, y = %X, y**2 = %X" % (b, y, ((y * y) % p)))
                 curve = {
                     'p': self.p,
                     'a': 0,
                     'b': b,
                     'n': self.n,
                     'bits': nbit
                 }
                 Generator.set_curve(curve)
                 P = Point(1, y)
                 assert P.is_valid()
                 Pnm1 = (self.n - 1) * P
                 Ptst = Pnm1 + P
                 Pa = P.affine()
                 if Ptst.is_infinite == True:
                     self.G = Generator(Pa[0], Pa[1])
                     self.b = b
                     break
         else:
             assert b is not None
             curve = {
                 'p': self.p,
                 'a': 0,
                 'b': b,
                 'n': self.n,
                 'bits': nbit
             }
             Generator.set_curve(curve)
             P = Point(G[0], G[1])
             # print("P = %s" % (P.uncompressed_format()))
             assert P.is_valid()
             Pnm1 = (self.n - 1) * P
             Ptst = Pnm1 + P
             Pa = P.affine()
             assert Ptst.is_infinite == True
             self.G = Generator(Pa[0], Pa[1])
             self.b = b
     #self.p = _pfunc(self.u)
     #self.n = _nfunc(self.u)
     print("u = %X (%d)" % (self.u, self.u))
     print("p = %X (%d)" % (self.p, self.p))
     print("n = %X (%d)" % (self.n, self.n))
     print("b = %X (%d)" % (self.b, self.b))
     print("P (compressed) = %s" % (self.G.compress()))
     print("P (uncompressed) = %s" % (self.G.uncompressed_format()))
Exemple #10
0
from fspke.icarthash import *
from ecpy.point import Point, Generator
from Crypto.Random import random

if __name__ == '__main__':
    import ecpy.curves as curves

    #_curve = curves.curve_secp112r1
    _curve = curves.curve_secp256k1
    #_curve = curves.curve_secp384r1
    #_curve = curves.curve_bauer9
    P = _curve['p']
    N = _curve['n']
    A = _curve['a']
    
    Generator.set_curve(_curve)


    #q = 1523
    #q = 491
    #q = 10667
    #q = 476039
    # a = 1
    # b = 0
    
    # q = 743
    # h = 24
    # r = 31
    # pairing = <pypbc.Pairing object at 0x1383630>
    # P = 04002B02E0
    q = 743
Exemple #11
0
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from ecpy.point import Point, Generator
import ecpy.curves as curves
import time
from Crypto.Random import random

#_curve = curves.curve_secp112r1
_curve = curves.curve_secp256k1
#_curve = curves.curve_secp384r1
#_curve = curves.curve_bauer9
P = _curve['p']
N = _curve['n']
A = _curve['a']

Generator.set_curve(_curve)

def modinv(a, m): 
    lastremainder, remainder, x, lastx = a, m, 0, 1
    while remainder:
        lastremainder, (quotient, remainder) = remainder, divmod(lastremainder, remainder)
        x, lastx = lastx - quotient*x, x
    return lastx % m

def inv(a, n):
    if a == 0:
        return 0
    lm, hm = 1, 0
    low, high = a % n, n
    while low > 1:
        r = high // low
Exemple #12
0
import hashlib
import base64
import json
import sys
from binascii import hexlify, unhexlify
import nak

from ecpy.curves import curve_secp256k1
from ecpy.point import Point, Generator
from ecpy.ecdsa import ECDSA
from Crypto.Random import random
from Crypto.Cipher import AES
from Crypto.Util import Counter

Point.set_curve(curve_secp256k1)
_G = Generator.init(curve_secp256k1['G'][0], curve_secp256k1['G'][1])
ECDSA.set_generator(_G)

client_p = random.randint(1, curve_secp256k1['n'] - 1)
client_P = _G * client_p

client_r = random.randint(1, curve_secp256k1['n'] - 1)
client_R = _G * client_r

ecdsa = ECDSA()

_server = "http://indigo.bounceme.net:5000/"
_server2 = "http://coopr8.com:5000/"
_server3 = "http://ciphrtxt.com:5000/"
_status = "api/status/"
_onion = "onion/"
Exemple #13
0
from ecpy.point import Point, Generator
import ecpy.curves as curves
from ecpy.ecdsa import ECDSA
from Crypto.Random import random
from Crypto.Cipher import AES
from Crypto.Util import Counter
import hashlib
import binascii
import base64

#_curve = curves.curve_secp112r1
_curve = curves.curve_secp256k1
#_curve = curves.curve_secp384r1

Point.set_curve(_curve)
_G = Generator.init(_curve['G'][0], _curve['G'][1])
ECDSA.set_curve(_curve)
ECDSA.set_generator(_G)

ecdsa = ECDSA()
recdsa = ECDSA()

friends = ['Alice', 'Bob', 'Carl', 'Donna', 'Eve']

data = []
for f in friends:
    datum = {}
    datum['name'] = f
    p = random.randint(1,_curve['n']-1)
    P = p * _G
    datum['privkey'] = p
Exemple #14
0
import hashlib
import base64
import json
from binascii import hexlify, unhexlify

from ecpy.curves import curve_secp256k1
from ecpy.point import Point, Generator
from ecpy.ecdsa import ECDSA
from Crypto.Random import random
from Crypto.Cipher import AES
from Crypto.Util import Counter

_curve = curve_secp256k1
Point.set_curve(_curve)
_G = Generator.init(_curve['G'][0], _curve['G'][1])
ECDSA.set_generator(_G)

server_p = random.randint(1, curve_secp256k1['n'] - 1)
server_P = _G * server_p

config = {}
config['receive_dir'] = "recv/"
config['message_dir'] = "messages/"
config['capacity'] = (128 * 1024 * 1024 * 1024)
config['max_file_size'] = (256 * 1024 * 1024)
config['ncache_sleep_interval'] = 30
config['version'] = '0.0.2'

clopts = []
clopts.append({'name': 'rpcuser', 'default': None})
from tornado.httpclient import AsyncHTTPClient, HTTPClient, HTTPRequest
import tornado.gen

from ecpy.curves import curve_secp256k1
from ecpy.point import Point, Generator
from ecpy.ecdsa import ECDSA
from Crypto.Random import random
from Crypto.Cipher import AES
from Crypto.Util import Counter

from threading import Lock

_C = curve_secp256k1
Point.set_curve(_C)

Generator.set_curve(_C)
_G = Generator.init(_C['G'][0], _C['G'][1])

ECDSA.set_generator(_G)
_ecdsa = ECDSA()

_statusPath = 'api/v2/status/'

_server_time = 'api/v2/time/'
_headers_since = 'api/v2/headers?since='
_download_message = 'api/v2/messages/'
_upload_message = 'api/v2/messages/'
_peer_list = 'api/v2/peers/'

_cache_expire_time = 5  # seconds
_high_water = 50
Exemple #16
0
from tornado.httpclient import AsyncHTTPClient, HTTPClient, HTTPRequest
import tornado.gen

from ecpy.curves import curve_secp256k1
from ecpy.point import Point, Generator
from ecpy.ecdsa import ECDSA
from Crypto.Random import random
from Crypto.Cipher import AES
from Crypto.Util import Counter

from threading import Lock

_C = curve_secp256k1
Point.set_curve(_C)

Generator.set_curve(_C)
_G = Generator.init(_C['G'][0], _C['G'][1])

ECDSA.set_generator(_G)
_ecdsa = ECDSA()

_statusPath = 'api/v2/status/'

_server_time = 'api/v2/time/'
_headers_since = 'api/v2/headers?since='
_download_message = 'api/v2/messages/'
_upload_message = 'api/v2/messages/'
_peer_list = 'api/v2/peers/'

_cache_expire_time = 5 # seconds
_high_water = 50