def _deserialize_header_v2(self, cmsg):
     if len(cmsg) < _header_size_b64_v2:
         return False
     binmsg = b64decode(cmsg[:_header_size_b64_v2])
     if binmsg[0:4] != _msg_api_ver_v2:
         return False
     hexmsg = hexlify(binmsg)
     self.time = int(hexmsg[8:16], 16)
     self.expire = int(hexmsg[16:24], 16)
     if not (hexmsg[24:26] == b'02' or hexmsg[24:26] == b'03'):
         return False
     if not (hexmsg[90:92] == b'02' or hexmsg[90:92] == b'03'):
         return False
     if not (hexmsg[156:158] == b'02' or hexmsg[156:158] == b'03'):
         return False
     self.I = Point.decompress(hexmsg[24:90])
     self.J = Point.decompress(hexmsg[90:156])
     self.K = Point.decompress(hexmsg[156:222])
     self.blocklen = int(hexmsg[222:230], 16)
     self.reserved = int(hexmsg[230:246], 16)
     # print('deserialize blocklen = ' + str(self.blocklen))
     if len(cmsg) >= _header_size_w_sig_b64_v2:
         sig_b64 = cmsg[_header_size_b64_v2:_header_size_w_sig_b64_v2]
         sighex = hexlify(b64decode(sig_b64))
         self.sig = (int(sighex[0:64], 16), int(sighex[64:128], 16))
         self.nonce = int(sighex[128:138], 16)
     return True
Beispiel #2
0
 def __init__(self, name=None):
     self.P = Point(0,0)
     self.version = _format_version_v2
     self.addr = {'mask': 0, 'mtgt': 0}
     self.t0 = 0
     self.ts = 0
     self.Tbk = ({'otp' : 0, 'T' : Point(0,0)})
     self.name = name
     self.metadata = {}
     self.initialized = False
     self.last_steps = None
     self.last_pubkey_point = None
 def refresh(self):
     req = HTTPRequest(self._baseurl() + _statusPath, method='GET')
     r = CTClient._sclient.fetch(req)
     if r.code != 200:
         return False
     pub = json.loads(r.body.decode('UTF-8'))['pubkey']
     self.Pkey = Point.decompress(pub.encode('UTF-8'))
     return True
Beispiel #4
0
 def refresh(self):
     req = HTTPRequest(self._baseurl() + _statusPath, method='GET')
     r = CTClient._sclient.fetch(req)
     if r.code != 200:
         return False
     pub = json.loads(r.body.decode('UTF-8'))['pubkey']
     self.Pkey = Point.decompress(pub.encode('UTF-8'))
     return True
Beispiel #5
0
 def deserialize(ikey):
     if isinstance(ikey, str):
         ikey = ikey.encode()
     # verify checksum
     inp = ikey.split(b':C')
     if len(inp) != 2:
         print('f1')
         return None
     ckck = hashlib.sha256(inp[0]).hexdigest()[-8:].encode().upper()
     if ckck != inp[1]:
         print('f2')
         return None
     # verify keys
     inp = inp[0].split(b':')
     if len(inp) < 7:
         print('f3')
         return None
     if ((inp[0][:1] != b'P') or (inp[1][:1] != b'K') or
             (inp[2][:1] != b'M') or (inp[3][:1] != b'N') or
             (inp[4][:1] != b'Z') or (inp[5][:1] != b'S') or
             (inp[6][:1] != b'R')):
         print('f4')
         return None
     # verify version
     if (inp[0][1:] != b'0200'):
         print('f5', inp[0])
         return None
     # decompress point
     z = PublicKey()
     z.P = Point.decompress(inp[1][1:])
     #
     z.addr['mask'] = int(inp[2][1:], 16)
     z.addr['mtgt'] = int(inp[3][1:], 16)
     z.t0 = int(inp[4][1:], 16)
     z.ts = int(inp[5][1:], 16)
     # time base key(s)
     ntbk = int(inp[6][1:])
     Tbk = []
     for i in range(ntbk):
         key = {}
         key['otp'] = int(inp[7 + (2 * i)][1:], 16)
         key['T'] = Point.decompress(inp[8 + (2 * i)][1:])
         Tbk.append(key)
     z.Tbk = Tbk
     z.initialized = True
     return z
Beispiel #6
0
 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 _deserialize_header_v1(self, cmsg):
     if len(cmsg) < _header_size_v1:
         return False
     hdrdata = cmsg[:_header_size_v1].split(b':')
     if len(hdrdata) != 6:
         return False
     if hdrdata[0] != _msg_api_ver_v1:
         return False
     self.time = int(hdrdata[1], 16)
     self.expire = int(hdrdata[2], 16)
     self.I = Point.decompress(hdrdata[3])
     self.J = Point.decompress(hdrdata[4])
     self.K = Point.decompress(hdrdata[5])
     self.version = "0100"
     if len(cmsg) >= _header_size_w_sig_v1:
         hdrdata = cmsg[:_header_size_w_sig_v1].split(b':')
         if len(hdrdata) != 8:
             return False
         self.sig = (int(hdrdata[6], 16), int(hdrdata[7], 16))
     return True
Beispiel #8
0
 def loadjson(msgjson):
     try:
         mdict = json.loads(msgjson)
         mnew = MessageFile()
         mnew.filepath = mdict['filepath']
         mnew.time = mdict['time']
         mnew.expire = mdict['expire']
         mnew.I = Point.decompress(mdict['I'])
         mnew.J = Point.decompress(mdict['J'])
         mnew.K = Point.decompress(mdict['K'])
         mnew.size = mdict['size']
         mnew.time_str = mdict['time_str']
         mnew.expire_str = mdict['expire_str']
         mnew.servertime = mdict['servertime']
         mnew.sig = mdict['signature']
         mnew.header = mdict['header']
         mnew.version = mdict['version']
         return mnew
     except:
         return None
Beispiel #9
0
 def uniformMap(self, n):
     """UniformMap maps values from Fq to E(Fq) in a uniform manner by
     elliptic curve point multiplication. While this does produce a uniform
     mapping within the ring of the generator point, using this map exposes
     the discrete logarithm of the resultant point (as log.G = n).
     """
     if (n != int(n)) or (n < 0):
         raise ValueError("Invalid Input")
     if n == 0:
         return Point(infinity=True, curve=self.curve)
     # just to be sure, force x to be a member of Fq
     u = int(n) % self.q
     return (self.G * u)
Beispiel #10
0
 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)
Beispiel #11
0
    def deterministicMap(self, n):
        """Using the original algorithm proposed by Thomas Icart, calculates
        a point on E(Fq) assuming n is a member of Fq. H(0) is mapped to O
        (point at infinity). Points are calculated in affine coordinates and
        returned as a Point Object.

        Note: deterministicMap reliably maps Fq to E(Fq), but as not all points
        on the curve can be parameterized, the results are not uniform and the
        distribution is differentiable from a collection of random points
        """
        if (n != int(n)) or (n < 0):
            raise ValueError("Invalid Input")
        if n == 0:
            return Point(infinity=True, curve=self.curve)
        # just to be sure, force x to be a member of Fq
        u = int(n) % self.q
        # print("u = ", u)
        u6_inv = pow((6 * u) % self.q, self.q - 2, self.q)
        assert ((6 * u * u6_inv) % self.q) == 1
        v = ((self._3a - pow(u, 4, self.q)) * u6_inv) % self.q
        u_6 = pow(u, 6, self.q)
        # print ("u_6 =", u_6)
        # print ("27_inv =",  self._27inv)
        u_6o27 = (pow(u, 6, self.q) * self._27inv) % self.q
        assert ((u_6o27 * 27) % self.q) == u_6
        foo = ((pow(v, 2, self.q) - self.b) - u_6o27) % self.q
        # print ("foo = ", foo)
        curootfoo = self._cubeRoot(foo)
        # print ("curootfoo = ", curootfoo)
        assert (pow(curootfoo, 3, self.q) == foo)
        u_2 = pow(u, 2, self.q)
        u_2o3 = (pow(u, 2, self.q) * self._3inv) % self.q
        assert ((u_2o3 * 3) % self.q) == u_2
        x = (curootfoo + u_2o3) % self.q
        y = ((u * x) + v) % self.q
        return Point(x, y, infinity=False, curve=self.curve)
Beispiel #12
0
 def refresh(self):
     r = None
     rtime = time.time()
     logging.info('refresh called for ' + self._baseurl())
     req = HTTPRequest(self._baseurl() + _statusPath,
                       method='GET',
                       connect_timeout=30,
                       request_timeout=60)
     try:
         r = sclient.fetch(req)
     except:
         self.fails += 1
         return False
     if r.code != 200:
         self.fails += 1
         return False
     status = json.loads(r.body.decode('UTF-8'))
     if 'pubkey' in status:
         self.Pkey = Point.decompress(status['pubkey'].encode('UTF-8'))
     if 'coinhost' in status:
         self.coinhost = status['coinhost']
     if 'coinport' in status:
         self.coinport = status['coinport']
     self.lastseen = rtime
     req = HTTPRequest(self._baseurl() + _peerListPath,
                       method='GET',
                       connect_timeout=30,
                       request_timeout=60)
     try:
         r = sclient.fetch(req)
     except (HTTPError, ConnectionRefusedError, TimeoutError):
         self.fails += 1
         return False
     if r.code != 200:
         self.fails += 1
         return False
     rlist = json.loads(r.body.decode('UTF-8'))
     self.peerlist = []
     for r in rlist:
         n = PeerListItem.loaddict(r)
         if n is not None:
             self.add_peer(n)
     self.peerlist.sort()
     self.fails = 0
     return True
Beispiel #13
0
 def loadjson(j):
     try:
         j = json.loads(j)
         n = PeerHost(j['host'], int(j['port']))
         if 'pubkey' in j:
             n.Pkey = Point.decompress(j['pubkey'])
         n.peerlist = []
         for li in j['peerlist']:
             nli = PeerListItem.loaddict(li)
             if nli is not None:
                 n.peerlist.append(nli)
         if 'coinhost' in j:
             n.coinhost = j['coinhost']
         if 'coinport' in j:
             n.coinhost = j['coinport']
         return n
     except:
         return None
Beispiel #14
0
 def loadjson(j):
     try:
         j = json.loads(j)
         n = PeerHost(j['host'], int(j['port']))
         if 'pubkey' in j:
             n.Pkey = Point.decompress(j['pubkey'])
         n.peerlist = []
         for li in j['peerlist']:
             nli = PeerListItem.loaddict(li)
             if nli is not None:
                 n.peerlist.append(nli)
         if 'coinhost' in j:
             n.coinhost = j['coinhost']
         if 'coinport' in j:
             n.coinhost = j['coinport']
         return n
     except:
         return None
Beispiel #15
0
 def refresh(self):
     r = None
     rtime = time.time()
     logging.info('refresh called for ' + self._baseurl())
     req = HTTPRequest(self._baseurl() + _statusPath, method='GET', connect_timeout=30, request_timeout=60)
     try:
         r = sclient.fetch(req)
     except:
         self.fails += 1
         return False
     if r.code != 200:
         self.fails += 1
         return False
     status = json.loads(r.body.decode('UTF-8'))
     if 'pubkey' in status:
         self.Pkey = Point.decompress(status['pubkey'].encode('UTF-8'))
     if 'coinhost' in status:
         self.coinhost = status['coinhost']
     if 'coinport' in status:
         self.coinport = status['coinport']
     self.lastseen = rtime
     req = HTTPRequest(self._baseurl() + _peerListPath, method='GET', connect_timeout=30, request_timeout=60)
     try:
         r = sclient.fetch(req)
     except (HTTPError, ConnectionRefusedError, TimeoutError) :
         self.fails += 1
         return False
     if r.code != 200:
         self.fails += 1
         return False
     rlist = json.loads(r.body.decode('UTF-8'))
     self.peerlist = []
     for r in rlist:
         n = PeerListItem.loaddict(r)
         if n is not None:
             self.add_peer(n)
     self.peerlist.sort()
     self.fails = 0
     return True
Beispiel #16
0
 def post(self, pubkey=None):
     if pubkey is None:
         self.set_status(400)
         self.finish()
     #logging.info('onion: received request')
     if len(pubkey) != 66:
         self.set_status(400)
         self.finish()
     #logging.info('onion: validated keylength')
         
     try:
         P = Point.decompress(pubkey)
     except:
         self.set_status(400)
         self.finish()
     
     ecdh = P * server_p
     keybin = hashlib.sha256(ecdh.compress()).digest()
     b = self.request.body
     bd = base64.b64decode(b)
     nakpubraw = hexlify(bd[:33])
     if not opts['standalone']:
         nakpub = ncache.get_nak(nakpubraw)
         if nakpub is None:
             self.set_status(400)
             self.finish()
         sig = (int(hexlify(bd[33:65]),16), int(hexlify(bd[65:97]),16))
         if not nakpub.verify(sig,bd[97:]):
             self.set_status(400)
             self.finish()
         logging.info('validated access for NAK %s' % nakpubraw)
     ivcount = int(hexlify(bd[97:113]),16)
     counter = Counter.new(128,initial_value=ivcount)
     cryptor = AES.new(keybin, AES.MODE_CTR, counter=counter)
     plaintext = cryptor.decrypt(bd[113:])
     plaintext = plaintext.decode('UTF-8')
     #logging.info('onion received: ' + plaintext)
     o_r = json.loads(plaintext)
     
     if o_r['local'] is True:
         if o_r['action'].lower() == 'get':
             o_server = 'http://127.0.0.1:' + str(opts['listenport']) + '/'
             o_path = o_r['url']
             self.client_R = Point.decompress(o_r['replykey'])
             req = tornado.httpclient.HTTPRequest(o_server+o_path,
                                                  method='GET', 
                                                  headers=o_r['headers'], 
                                                  connect_timeout=30, 
                                                  request_timeout=60)
             onion_client.fetch(req, self.callback_encrypt)
         elif o_r['action'].lower() == 'post':
             o_server = 'http://127.0.0.1:' + str(opts['listenport']) + '/'
             o_path = o_r['url']
             self.client_R = Point.decompress(o_r['replykey'])
             req = tornado.httpclient.HTTPRequest(o_server+o_path,
                                                  method='POST',
                                                  body=o_r['body'],
                                                  headers=o_r['headers'], 
                                                  connect_timeout=30,
                                                  request_timeout=60)
             onion_client.fetch(req, self.callback_encrypt)
     else:
         if nak is None:
             self.set_status(400)
             self.finish()
         if (len(o_r['pubkey']) != 66) or not((o_r['pubkey'][:2] == '02') or
                                              (o_r['pubkey'][:2] == '03')):
             self.set_status(400)
             self.finish()
         try:
             i = int(o_r['pubkey'],16)
         except:
             self.set_status(400)
             self.finish()
         o_server = 'http://' + o_r['host'] + ':' + str(o_r['port']) + '/'
         o_path = 'onion/' + o_r['pubkey']
         o_raw = base64.b64decode(o_r['body'])
         sig = nak.sign(o_raw)
         o_body = base64.b64encode(nakpubbin + unhexlify('%064x' % sig[0]) + 
                                   unhexlify('%064x' % sig[1]) + o_raw)
         req = tornado.httpclient.HTTPRequest(o_server+o_path,
                                              method='POST', 
                                              body=o_body,
                                              connect_timeout=30,
                                              request_timeout=60)
         onion_client.fetch(req, self.callback)
Beispiel #17
0
import requests
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/"
Beispiel #18
0
# 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 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
Beispiel #19
0
 iH2 = IcartHash.deserialize(iH.serialize())
 print("iH(0) = ", h0)
 for i in range(0, q):
     # n = random.randint(0,q-1)
     n = i
     hn = iH.hashval(n)
     assert hn == iH2.hashval(n)
     ncollisions = 0
     coll = []
     for j in range(0, q):
         hc = iH.hashval(j)
         if (i != j) and (hc == hn):
             ncollisions += 1
             # print("collision i, j, hash = ", i, j, hc)
             coll.append(j)
     hp = Point(infinity=True, curve=curve)
     if hn[1] == False:
         hp = Point.decompress(hn[0])
     ha = hp.affine()
     han = (ha[0], ha[1], hp.is_infinite)
     if ncollisions > 0:
         print("n, iH(n) = ", n, han, ":", ncollisions, "collisions", coll)
     else:
         print("n, iH(n) = ", n, han)
     x,y = han[0], han[1]
     R = Point(x, y, infinity=han[2])
     assert R.is_valid()
     Q = R + G
     assert Q.is_valid()
     rt = (pow(x, 3, q) + (a * x) + b) % q
     lf = pow(y, 2, q)
Beispiel #20
0
import requests
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/"
Beispiel #21
0
    return from_jacobian(jacobian_add(to_jacobian(a), to_jacobian(b)))

if __name__ == '__main__':
    p = _curve['p']
    if False:
        for x in range(min(512,p)):
            xi = inv(x, p)
            test = (x*xi) % p
            #print x, xi, x*xi, test
            if x != 0:
                assert test == 1
    
    print('Setting up Generators')
    G = _curve['G']
    print('ref Gen ' + str(G))
    Gpt = Point(G[0],G[1])
    print('Point Gen ' + str(Gpt))
    GenG = Generator.init(G[0],G[1])
    print('Generator Gen ' + str(GenG))
    GenG2 = Generator.init(G[0],G[1])
    print('Generator Gen ' + str(GenG2))
    assert GenG2 is GenG
    assert Gpt.is_valid()
    assert GenG.is_valid()
    print('Generator uncompressed ' + str(GenG.uncompressed_format()))
    InfP = Point()
    ex = InfP.compress()
    exraw = InfP.uncompressed_format()
    InfP2 = Point.decompress(ex)
    InfP3 = Point.decompress(exraw)
    InfP4 = Point.decompress(ex.decode())
Beispiel #22
0
# 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
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.init(_C['G'][0], _C['G'][1])

_network_id = {
    'ct-indigo': { 'pub': b'1c', 'priv': b'bb' },
    'ct-red': { 'pub': b'50', 'priv': b'a3' },
    'bt-main': { 'pub': b'00', 'priv': b'80' },
    'bt-test': { 'pub': b'6f', 'priv': b'ef' },
    'bt-simtest': { 'pub': b'3f', 'priv': b'64' },
}

_pfmt = '%%0%dx' % (((_C['bits'] + 7) >> 3) << 1)
_default_network = _network_id['ct-indigo']


class WalletPubkey (object):
Beispiel #23
0
from binascii import hexlify, unhexlify
import json
import logging
import time
import os
import random
from tornado.httpclient import HTTPClient, HTTPRequest, HTTPError
from lbr import lbr
from msgstoreclient import MsgStore
import ctcoin.rpc

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

_curve = curve_secp256k1
Point.set_curve(_curve)

_default_port = 7754
_default_coin_port = 7764
_default_max_age = (4 * 60 * 60)  # 4 hours
_default_max_fails = 1

_statusPath = 'api/v2/status/'
_peerListPath = 'api/v2/peers/'
_peerUpdatePath = 'api/v2/peers/'

_peer_msync_timeout = 10
_peer_psync_interval = (2 * 60)  # 2 minutes

sclient = HTTPClient()
Beispiel #24
0
# 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
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.init(_C['G'][0], _C['G'][1])

_network_id = {
    'ct-indigo': {
        'pub': b'1c',
        'priv': b'bb'
    },
    'ct-red': {
        'pub': b'50',
        'priv': b'a3'
    },
    'bt-main': {
        'pub': b'00',
        'priv': b'80'
    },
Beispiel #25
0
# 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
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
Beispiel #26
0
from binascii import hexlify, unhexlify
import json
import logging
import time
import os
import random
from tornado.httpclient import HTTPClient, HTTPRequest, HTTPError
from lbr import lbr
from msgstoreclient import MsgStore
import ctcoin.rpc

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

_curve = curve_secp256k1
Point.set_curve(_curve)

_default_port=7754
_default_coin_port=7764
_default_max_age=(4*60*60)    # 4 hours
_default_max_fails=1

_statusPath = 'api/v2/status/'
_peerListPath = 'api/v2/peers/'
_peerUpdatePath = 'api/v2/peers/'

_peer_msync_timeout = 10
_peer_psync_interval = (2*60)   # 2 minutes

sclient = HTTPClient()
Beispiel #27
0
class PublicKey (object):
    def __init__(self, name=None):
        self.P = Point(0,0)
        self.version = _format_version_v2
        self.addr = {'mask': 0, 'mtgt': 0}
        self.t0 = 0
        self.ts = 0
        self.Tbk = ({'otp' : 0, 'T' : Point(0,0)})
        self.name = name
        self.metadata = {}
        self.initialized = False
        self.last_steps = None
        self.last_pubkey_point = None

    def set_metadata(self, metakey, metavalue):
        self.metadata[metakey] = metavalue

    def get_metadata(self, metakey):
        if metakey not in self.metadata:
            return None
        return self.metadata[metakey]

    def label(self):
        txt = str(self.P)[:8]
        if self.name:
            txt = self.name + '_' + txt
        return txt

    def current_pubkey_point(self, timeval=None):
        """Calulates the current EC public key point as a pseudorandom linear
        combination of the primary P key and multiple time-based T keys using
        an algorithm based on HOTP/TOTP"""
        if not self.initialized:
            return None
        if timeval is None:
            timeval = int(time.time())
        steps = (timeval - self.t0) / self.ts
        if steps == self.last_steps:
            return self.last_pubkey_point
        P = self.P
        for i in range(len(self.Tbk)):
            okeyt = (_pfmt % (self.Tbk[i]['otp'])).encode()
            stepsd = ('%07d' % (steps % 10000000)).encode()
            otphmac = hmac.new(okeyt, stepsd, hashlib.sha256)
            hashv = otphmac.hexdigest()
            hashi = int(hashv, 16) % _C['p']
            S = (self.Tbk[i]['T']) * hashi
            P = S + P
        self.last_steps = steps
        self.last_pubkey_point = P
        return P

    def serialize_pubkey(self):
        ekey = ('P%04x' % self.version).encode()
        ekey += b':K' + self.P.compress().upper()
        ekey += b':M' + (_Mfmt % self.addr['mask']).encode()
        ekey += b':N' + (_Mfmt % self.addr['mtgt']).encode()
        ekey += b':Z' + ('%08X' % self.t0).encode()
        ekey += b':S' + ('%08X' % self.ts).encode()
        ekey += b':R' + ('%04X' % len(self.Tbk)).encode()
        for Tbk in self.Tbk:
            ekey += b':F' + (_Pfmt % Tbk['otp']).encode()
            ekey += b':T' + Tbk['T'].compress().upper()
        ekey += b':C' + (hashlib.sha256(ekey).hexdigest()[-8:]).encode().upper()
        return ekey

    def serialize(self):
        return self.serialize_pubkey()

    @staticmethod
    def deserialize(ikey):
        if isinstance(ikey, str):
            ikey = ikey.encode()
        # verify checksum
        inp = ikey.split(b':C')
        if len(inp) != 2:
            print('f1')
            return None
        ckck = hashlib.sha256(inp[0]).hexdigest()[-8:].encode().upper()
        if ckck != inp[1]:
            print('f2')
            return None
        # verify keys
        inp = inp[0].split(b':')
        if len(inp) < 7:
            print('f3')
            return None
        if ((inp[0][:1] != b'P') or (inp[1][:1] != b'K') or
                (inp[2][:1] != b'M') or (inp[3][:1] != b'N') or
                (inp[4][:1] != b'Z') or (inp[5][:1] != b'S') or
                (inp[6][:1] != b'R')):
            print('f4')
            return None
        # verify version
        if (inp[0][1:] != b'0200'):
            print('f5', inp[0])
            return None
        # decompress point
        z = PublicKey()
        z.P = Point.decompress(inp[1][1:])
        #
        z.addr['mask'] = int(inp[2][1:], 16)
        z.addr['mtgt'] = int(inp[3][1:], 16)
        z.t0 = int(inp[4][1:], 16)
        z.ts = int(inp[5][1:], 16)
        # time base key(s)
        ntbk = int(inp[6][1:])
        Tbk = []
        for i in range(ntbk):
            key = {}
            key['otp'] = int(inp[7 + (2 * i)][1:], 16)
            key['T'] = Point.decompress(inp[8 + (2 * i)][1:])
            Tbk.append(key)
        z.Tbk = Tbk
        z.initialized = True
        return z
    
    def __str__(self):
        return self.serialize().decode()
    
    def __repr__(self):
        return 'PublicKey.deserialize(' + self.serialize() + ')'
Beispiel #28
0
# 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
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
Beispiel #29
0
    def post(self, pubkey=None):
        if pubkey is None:
            self.set_status(400)
            self.finish()
        #logging.info('onion: received request')
        if len(pubkey) != 66:
            self.set_status(400)
            self.finish()
        #logging.info('onion: validated keylength')

        try:
            P = Point.decompress(pubkey)
        except:
            self.set_status(400)
            self.finish()

        ecdh = P * server_p
        keybin = hashlib.sha256(ecdh.compress()).digest()
        b = self.request.body
        bd = base64.b64decode(b)
        nakpubraw = hexlify(bd[:33])
        if not opts['standalone']:
            nakpub = ncache.get_nak(nakpubraw)
            if nakpub is None:
                self.set_status(400)
                self.finish()
            sig = (int(hexlify(bd[33:65]), 16), int(hexlify(bd[65:97]), 16))
            if not nakpub.verify(sig, bd[97:]):
                self.set_status(400)
                self.finish()
            logging.info('validated access for NAK %s' % nakpubraw)
        ivcount = int(hexlify(bd[97:113]), 16)
        counter = Counter.new(128, initial_value=ivcount)
        cryptor = AES.new(keybin, AES.MODE_CTR, counter=counter)
        plaintext = cryptor.decrypt(bd[113:])
        plaintext = plaintext.decode('UTF-8')
        #logging.info('onion received: ' + plaintext)
        o_r = json.loads(plaintext)

        if o_r['local'] is True:
            if o_r['action'].lower() == 'get':
                o_server = 'http://127.0.0.1:' + str(opts['listenport']) + '/'
                o_path = o_r['url']
                self.client_R = Point.decompress(o_r['replykey'])
                req = tornado.httpclient.HTTPRequest(o_server + o_path,
                                                     method='GET',
                                                     headers=o_r['headers'],
                                                     connect_timeout=30,
                                                     request_timeout=60)
                onion_client.fetch(req, self.callback_encrypt)
            elif o_r['action'].lower() == 'post':
                o_server = 'http://127.0.0.1:' + str(opts['listenport']) + '/'
                o_path = o_r['url']
                self.client_R = Point.decompress(o_r['replykey'])
                req = tornado.httpclient.HTTPRequest(o_server + o_path,
                                                     method='POST',
                                                     body=o_r['body'],
                                                     headers=o_r['headers'],
                                                     connect_timeout=30,
                                                     request_timeout=60)
                onion_client.fetch(req, self.callback_encrypt)
        else:
            if nak is None:
                self.set_status(400)
                self.finish()
            if (len(o_r['pubkey']) != 66) or not (
                (o_r['pubkey'][:2] == '02') or (o_r['pubkey'][:2] == '03')):
                self.set_status(400)
                self.finish()
            try:
                i = int(o_r['pubkey'], 16)
            except:
                self.set_status(400)
                self.finish()
            o_server = 'http://' + o_r['host'] + ':' + str(o_r['port']) + '/'
            o_path = 'onion/' + o_r['pubkey']
            o_raw = base64.b64decode(o_r['body'])
            sig = nak.sign(o_raw)
            o_body = base64.b64encode(nakpubbin + unhexlify('%064x' % sig[0]) +
                                      unhexlify('%064x' % sig[1]) + o_raw)
            req = tornado.httpclient.HTTPRequest(o_server + o_path,
                                                 method='POST',
                                                 body=o_body,
                                                 connect_timeout=30,
                                                 request_timeout=60)
            onion_client.fetch(req, self.callback)
 def _decompress(self):
     self.I = Point.decompress(self._Iraw)
     self.J = Point.decompress(self._Jraw)
     self.K = Point.decompress(self._Kraw)
 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()))