├── README.md ├── construction-0 ├── README.md ├── btclient0.py ├── btclient1.py ├── btcrypto.py ├── btfiler.py ├── btpeer.py ├── btringoram.py ├── btserver0.py ├── btserverfiler.py ├── btserverpeer.py ├── createfile.py ├── dummy.txt ├── kill.py └── shell.py └── construction-1 ├── README.md ├── auto.py ├── btclient0.py ├── btclient2.py ├── btcrypto.py ├── btfiler.py ├── btpeer.py ├── btserver0.py ├── btserverfiler.py ├── btserverpeer.py ├── ecc ├── AffineCurvePoint.py ├── CurveDB.py ├── ECPrivateKey.py ├── ECPublicKey.py ├── EllipticCurve.py ├── FieldElement.py ├── MontgomeryCurve.py ├── PointOps.py ├── PrivKeyOps.py ├── PubKeyOps.py ├── Random.py ├── ShortWeierstrassCurve.py ├── Singleton.py ├── Tools.py ├── TwistedEdwardsCurve.py ├── __init__.py └── tests │ ├── CryptoOpsTests.py │ ├── CurveTests.py │ ├── ECTests.py │ ├── Ed25519BasicTests.py │ ├── Ed25519ExtdTests.py │ ├── FieldElementSqrtTests.py │ ├── FieldElementTests.py │ ├── FullTests.py │ ├── TwEdMontConversionTests.py │ ├── TwEdMontDomainTests.py │ └── __init__.py ├── itpiroram.py └── kill.py /README.md: -------------------------------------------------------------------------------- 1 | # OblivP2P: An Oblivious Peer-to-Peer Content Sharing System 2 | ### Implementation for OblivP2P (construction-0 and construction-1(unoptimized)) 3 | ================================================================================ 4 | 5 | -------------------------------------------------------------------------------- 6 | Authors 7 | -------------------------------------------------------------------------------- 8 | 9 | The OblivP2P is designed by Yaoqi Jia, Tarik Moataz, Shruti Tople and Prateek Saxena; 10 | developed and currently maintained by [Yaoqi Jia]. 11 | 12 | 13 | -------------------------------------------------------------------------------- 14 | Disclaimer 15 | -------------------------------------------------------------------------------- 16 | 17 | The code is a research-quality proof of concept, and is still under development for more features and bug-fixing. 18 | 19 | -------------------------------------------------------------------------------- 20 | References 21 | -------------------------------------------------------------------------------- 22 | 23 | \[jiaoblivp2p] [ 24 | _OBLIVP2P: An Oblivious Peer-to-Peer Content Sharing System_ 25 | ] (http://www.comp.nus.edu.sg/~jiayaoqi/publications/oblivp2p_usenix.pdf) 26 | 27 | Yaoqi Jia, Tarik Moataz, Shruti Tople and Prateek Saxena. 28 | 29 | In the 25th USENIX Security Symposium (Usenix Security 2016) 30 | 31 | [Yaoqi Jia]: http://www.comp.nus.edu.sg/~jiayaoqi/ 32 | 33 | -------------------------------------------------------------------------------- /construction-0/README.md: -------------------------------------------------------------------------------- 1 | ### Requirement: python-crypto 2 | 3 | ### Set up tracker: 4 | #### python btserver0.py tracker-host tracker-port max-peers default-ip:port 5 | $ python btserver0.py 127.0.0.1 7090 0 0.0.0.0:8090 6 | 7 | ### Set up 2^(N+1) - 1 nodes: 8 | $ python shell.py N 9 | 10 | ### Client requests to upload/fetch blocks: 11 | #### python btclient1.py -c 1 peer-host peer-port max-peers tracker-ip:port 12 | $ python btclient1.py -c 1 127.0.0.1 20000 0 127.0.0.1:7090 13 | 14 | ### Stop running nodes (kill all running python processes): 15 | $ python kill.py 16 | 17 | ### Create files with a specific size (N kB): 18 | $ python createfile.py N 19 | 20 | -------------------------------------------------------------------------------- /construction-0/btclient0.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import sys 4 | import threading 5 | 6 | from random import * 7 | 8 | from btfiler import * 9 | 10 | 11 | 12 | class BtClient: 13 | def __init__( self, firstpeer, hops=2, maxpeers=5, serverport=5678, serverhost=None, master=None ): 14 | self.btpeer = FilerPeer( maxpeers, serverport, serverhost ) 15 | 16 | #self.bind( "", self.__onDestroy ) 17 | 18 | host,port = firstpeer.split(':') 19 | 20 | t = threading.Thread( target = self.btpeer.mainloop, args = [] ) 21 | t.start() 22 | self.btpeer.startstabilizer( self.btpeer.checklivepeers, 3 ) 23 | 24 | 25 | def naiveinit(self, peerid): 26 | #response = self.btpeer.sendtopeer( peerid, NAIVEINIT, self.btpeer.myid ) 27 | print peerid 28 | host,port = peerid.split(':') 29 | resp = self.btpeer.connectandsend( host, port, NAIVEINIT, self.btpeer.myid ) 30 | #print peerid + NAIVEINIT + self.btpeer.myid 31 | #print str(resp) 32 | if len(resp) > 0: 33 | data = resp[0][1] 34 | self.btpeer.bucketdata = str(data).split('>>>') 35 | number = self.btpeer.bucketdata[0] 36 | del self.btpeer.bucketdata[0] 37 | #print number + " " + str(self.btpeer.bucketdata) 38 | 39 | def uploaddata( self, peerid, dataid, datacontent ): 40 | host,port = peerid.split(':') 41 | senddata = dataid + ">>>" + datacontent 42 | resp = self.btpeer.connectandsend(host, port, UPLOADDATA, senddata) 43 | #data = resp[0][1] 44 | print resp 45 | 46 | def readdata( self, peerid, dataid ): 47 | host,port = peerid.split(':') 48 | resp = self.btpeer.connectandsend(host, port, READDATA, dataid) 49 | print "readdata" 50 | #data = resp[0][1] 51 | print resp 52 | 53 | def btdebug(self, msg): 54 | """ Prints a messsage to the screen with the name of the current thread """ 55 | print "[%s] %s" % ( str(threading.currentThread().getName()), msg ) 56 | 57 | 58 | def main(): 59 | if len(sys.argv) < 7: 60 | print "Syntax: %s -c 1 server-host server-port max-peers tracker-ip:port" % sys.argv[0] 61 | sys.exit(-1) 62 | if sys.argv[3] != "0": 63 | serverhost = sys.argv[3] 64 | else: 65 | serverhost = None 66 | serverport = int(sys.argv[4]) 67 | maxpeers = sys.argv[5] 68 | peerid = sys.argv[6] 69 | app = BtClient( firstpeer=peerid, maxpeers=maxpeers, serverport=serverport, serverhost=serverhost ) 70 | #app.mainloop() 71 | #t = threading.Thread( target = app.mainloop(), args = [] ) 72 | #t.start() 73 | app.naiveinit(peerid) 74 | 75 | 76 | # setup and run app 77 | if __name__=='__main__': 78 | main() 79 | -------------------------------------------------------------------------------- /construction-0/btclient1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | 4 | import sys 5 | import threading 6 | import random 7 | import time 8 | 9 | from btfiler import * 10 | 11 | 12 | 13 | class BtClient: 14 | def __init__( self, firstpeer, hops=2, maxpeers=5, serverport=5678, serverhost=None, master=None ): 15 | 16 | self.btpeer = FilerPeer( maxpeers, serverport, serverhost ) 17 | host,port = firstpeer.split(':') 18 | 19 | t = threading.Thread( target = self.btpeer.mainloop, args = [] ) 20 | t.start() 21 | self.btpeer.startstabilizer( self.btpeer.checklivepeers, 3 ) 22 | 23 | 24 | def naiveinit(self, peerid): 25 | print peerid 26 | host,port = peerid.split(':') 27 | resp = self.btpeer.connectandsend( host, port, NAIVEINIT, self.btpeer.myid ) 28 | 29 | if len(resp) > 0: 30 | data = resp[0][1] 31 | self.btpeer.bucketdata = str(data).split('>>>') 32 | number = self.btpeer.bucketdata[0] 33 | del self.btpeer.bucketdata[0] 34 | print number + " " + str(self.btpeer.bucketdata) 35 | 36 | def uploaddata( self, peerid, dataid, datacontent ): 37 | self.btpeer.uploadstarttime = time.time() 38 | host,port = peerid.split(':') 39 | senddata = dataid + ">>>" + datacontent 40 | resp = self.btpeer.connectandsend(host, port, UPLOADDATA, senddata) 41 | data = resp[0][1] 42 | print "uploaddata finished." 43 | print "Time takes " + str(time.time() - self.btpeer.uploadstarttime) 44 | print "first 20 bytes" 45 | print data[:20] 46 | 47 | def readdata( self, peerid, dataid ): 48 | self.btpeer.readstarttime = time.time() 49 | host,port = peerid.split(':') 50 | resp = self.btpeer.connectandsend(host, port, READDATA, dataid) 51 | print "readdata finished." 52 | print "Time takes " + str(time.time() - self.btpeer.readstarttime) 53 | data = resp[0][1] 54 | print "first 20 bytes" 55 | print data[:20] 56 | #return data 57 | 58 | def btdebug(self, msg): 59 | """ Prints a messsage to the screen with the name of the current thread """ 60 | print "[%s] %s" % ( str(threading.currentThread().getName()), msg ) 61 | 62 | 63 | def main(): 64 | if len(sys.argv) < 7: 65 | print "Syntax: %s -c 1 server-host server-port max-peers tracker-ip:port" % sys.argv[0] 66 | sys.exit(-1) 67 | if sys.argv[3] != "0": 68 | serverhost = sys.argv[3] 69 | else: 70 | serverhost = None 71 | serverport = int(sys.argv[4]) 72 | maxpeers = sys.argv[5] 73 | peerid = sys.argv[6] 74 | app = BtClient( firstpeer=peerid, maxpeers=maxpeers, serverport=serverport, serverhost=serverhost ) 75 | #app.mainloop() 76 | #t = threading.Thread( target = app.mainloop(), args = [] ) 77 | #t.start() 78 | app.naiveinit(peerid) 79 | 80 | N = 3 81 | dummypath = "." 82 | uploadN = 3 83 | accessN = 2**N 84 | 85 | fd = file(dummypath + "/dummy.txt", 'r') 86 | dummydata = '' 87 | while True: 88 | filedata = fd.read(2048) 89 | if not len(filedata): 90 | break 91 | dummydata += filedata 92 | #print dummydata 93 | fd.close() 94 | realdata = dummydata 95 | 96 | for i in range(uploadN): 97 | if i < 10: 98 | app.uploaddata(peerid, "data"+str(i), realdata.replace("rese", "res"+str(i))) 99 | elif i < 100: 100 | app.uploaddata(peerid, "data"+str(i), realdata.replace("rese", "re"+str(i))) 101 | elif i< 1000: 102 | app.uploaddata(peerid, "data"+str(i), realdata.replace("rese", "r"+str(i))) 103 | else: 104 | app.uploaddata(peerid, "data"+str(i), realdata.replace("rese", str(i))) 105 | 106 | mockreadsequence = [] 107 | for i in range(accessN): 108 | n = random.randint(0, uploadN-1) 109 | mockreadsequence.append("data"+str(n)) 110 | 111 | for i in mockreadsequence: 112 | #if the first 20 bytes contains the requested dataid, e.g., "res2minate" contains 2, then the result is correct 113 | print "Read data: %s" % i 114 | app.readdata(peerid, i) 115 | 116 | # setup and run app 117 | if __name__=='__main__': 118 | main() 119 | -------------------------------------------------------------------------------- /construction-0/btcrypto.py: -------------------------------------------------------------------------------- 1 | import base64 2 | import os 3 | from Crypto.Cipher import AES 4 | from Crypto import Random 5 | from Crypto.Random import random 6 | from random import shuffle 7 | 8 | class AESCipher: 9 | 10 | def __init__( self, key ): 11 | self.key = key 12 | self.BS = 16 13 | self.pad = lambda s: s + (self.BS - len(s) % self.BS) * chr(self.BS - len(s) % self.BS) 14 | self.unpad = lambda s : s[:-ord(s[len(s)-1:])] 15 | 16 | def encrypt( self, raw ): 17 | raw = self.pad(raw) 18 | #print AES.block_size 19 | iv = Random.new().read( AES.block_size ) 20 | cipher = AES.new( self.key, AES.MODE_CBC, iv ) 21 | return base64.b64encode( iv + cipher.encrypt( raw ) ) 22 | 23 | def decrypt( self, enc ): 24 | enc = base64.b64decode(enc) 25 | iv = enc[:16] 26 | cipher = AES.new(self.key, AES.MODE_CBC, iv ) 27 | return self.unpad(cipher.decrypt( enc[16:] )) 28 | 29 | def generateKey( size ): 30 | return Random.new().read(size) 31 | 32 | def generaterandomchoice( choicelist ): 33 | return random.choice(choicelist) 34 | 35 | -------------------------------------------------------------------------------- /construction-0/btpeer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # btpeer.py 4 | 5 | import socket 6 | import struct 7 | import threading 8 | import time 9 | import traceback 10 | import itertools 11 | 12 | 13 | def btdebug( msg ): 14 | """ Prints a messsage to the screen with the name of the current thread """ 15 | print "[%s] %s" % ( str(threading.currentThread().getName()), msg ) 16 | 17 | 18 | #============================================================================== 19 | class BTPeer: 20 | """ Implements the core functionality that might be used by a peer in a 21 | P2P network. 22 | 23 | """ 24 | 25 | #-------------------------------------------------------------------------- 26 | def __init__( self, maxpeers, serverport, myid=None, serverhost = None ): 27 | #-------------------------------------------------------------------------- 28 | """ Initializes a peer servent (sic.) with the ability to catalog 29 | information for up to maxpeers number of peers (maxpeers may 30 | be set to 0 to allow unlimited number of peers), listening on 31 | a given server port , with a given canonical peer name (id) 32 | and host address. If not supplied, the host address 33 | (serverhost) will be determined by attempting to connect to an 34 | Internet host like Google. 35 | 36 | """ 37 | self.debug = 0 38 | 39 | self.bucketdata = [] 40 | self.uploadstarttime = 0 41 | self.readstarttime = 0 42 | 43 | 44 | self.maxpeers = int(maxpeers) 45 | self.serverport = int(serverport) 46 | #serverhost = "127.0.0.1" 47 | if serverhost: self.serverhost = serverhost 48 | else: self.__initserverhost() 49 | 50 | if myid: self.myid = myid 51 | else: self.myid = '%s:%d' % (self.serverhost, self.serverport) 52 | 53 | self.peerlock = threading.Lock() # ensure proper access to 54 | # peers list (maybe better to use 55 | # threading.RLock (reentrant)) 56 | self.peers = {} # peerid ==> (host, port) mapping 57 | self.shutdown = False # used to stop the main loop 58 | 59 | self.handlers = {} 60 | self.router = None 61 | 62 | 63 | 64 | #-------------------------------------------------------------------------- 65 | def __initserverhost( self ): 66 | #-------------------------------------------------------------------------- 67 | """ Attempt to connect to an Internet host in order to determine the 68 | local machine's IP address. 69 | 70 | """ 71 | s = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) 72 | s.connect( ( "www.google.com", 80 ) ) 73 | self.serverhost = s.getsockname()[0] 74 | s.close() 75 | 76 | 77 | 78 | #-------------------------------------------------------------------------- 79 | def __debug( self, msg ): 80 | #-------------------------------------------------------------------------- 81 | if self.debug: 82 | btdebug( msg ) 83 | 84 | 85 | 86 | #-------------------------------------------------------------------------- 87 | def __handlepeer( self, clientsock ): 88 | #-------------------------------------------------------------------------- 89 | """ 90 | handlepeer( new socket connection ) -> () 91 | 92 | Dispatches messages from the socket connection 93 | """ 94 | 95 | self.__debug( 'New child ' + str(threading.currentThread().getName()) ) 96 | self.__debug( 'Connected ' + str(clientsock.getpeername()) ) 97 | 98 | host, port = clientsock.getpeername() 99 | peerconn = BTPeerConnection( None, host, port, clientsock, debug=False ) 100 | 101 | try: 102 | msgtype, msgdata = peerconn.recvdata() 103 | if msgtype: msgtype = msgtype.upper() 104 | if msgtype not in self.handlers: 105 | self.__debug( 'Not handled: %s: %s' % (msgtype, msgdata) ) 106 | else: 107 | self.__debug( 'Handling peer msg: %s: %s' % (msgtype, msgdata) ) 108 | self.handlers[ msgtype ]( peerconn, msgdata ) 109 | except KeyboardInterrupt: 110 | raise 111 | except: 112 | if self.debug: 113 | traceback.print_exc() 114 | 115 | #self.__debug( 'Disconnecting ' + str(clientsock.getpeername()) ) 116 | peerconn.close() 117 | 118 | # end handlepeer method 119 | 120 | 121 | 122 | #-------------------------------------------------------------------------- 123 | def __runstabilizer( self, stabilizer, delay ): 124 | #-------------------------------------------------------------------------- 125 | while not self.shutdown: 126 | stabilizer() 127 | time.sleep( delay ) 128 | 129 | 130 | 131 | #-------------------------------------------------------------------------- 132 | def setmyid( self, myid ): 133 | #-------------------------------------------------------------------------- 134 | self.myid = myid 135 | 136 | 137 | 138 | #-------------------------------------------------------------------------- 139 | def startstabilizer( self, stabilizer, delay ): 140 | #-------------------------------------------------------------------------- 141 | """ Registers and starts a stabilizer function with this peer. 142 | The function will be activated every seconds. 143 | 144 | """ 145 | t = threading.Thread( target = self.__runstabilizer, 146 | args = [ stabilizer, delay ] ) 147 | t.start() 148 | 149 | 150 | 151 | #-------------------------------------------------------------------------- 152 | def addhandler( self, msgtype, handler ): 153 | #-------------------------------------------------------------------------- 154 | """ Registers the handler for the given message type with this peer """ 155 | assert len(msgtype) == 4 156 | self.handlers[ msgtype ] = handler 157 | 158 | 159 | 160 | #-------------------------------------------------------------------------- 161 | def addrouter( self, router ): 162 | #-------------------------------------------------------------------------- 163 | """ Registers a routing function with this peer. The setup of routing 164 | is as follows: This peer maintains a list of other known peers 165 | (in self.peers). The routing function should take the name of 166 | a peer (which may not necessarily be present in self.peers) 167 | and decide which of the known peers a message should be routed 168 | to next in order to (hopefully) reach the desired peer. The router 169 | function should return a tuple of three values: (next-peer-id, host, 170 | port). If the message cannot be routed, the next-peer-id should be 171 | None. 172 | 173 | """ 174 | self.router = router 175 | 176 | #-------------------------------------------------------------------------- 177 | def generatebitstrings( self, number ): 178 | #-------------------------------------------------------------------------- 179 | """ Generate bitstrings for a number 180 | 181 | """ 182 | bitstrings = ['R'] 183 | for i in range( 1, number+1 ): 184 | for j in itertools.product( '01', repeat=i ): 185 | bits = [''.join(j)] 186 | bitstrings += bits 187 | return bitstrings 188 | 189 | #-------------------------------------------------------------------------- 190 | def addpeer( self, peerid, host, port ): 191 | #-------------------------------------------------------------------------- 192 | """ Adds a peer name and host:port mapping to the known list of peers. 193 | 194 | """ 195 | if peerid not in self.peers and (self.maxpeers == 0 or 196 | len(self.peers) < self.maxpeers): 197 | self.peers[ peerid ] = (host, int(port)) 198 | return True 199 | else: 200 | return False 201 | 202 | #-------------------------------------------------------------------------- 203 | def getpeer( self, peerid ): 204 | #-------------------------------------------------------------------------- 205 | """ Returns the (host, port) tuple for the given peer name """ 206 | assert peerid in self.peers # maybe make this just a return NULL? 207 | return self.peers[ peerid ] 208 | 209 | 210 | 211 | #-------------------------------------------------------------------------- 212 | def removepeer( self, peerid ): 213 | #-------------------------------------------------------------------------- 214 | """ Removes peer information from the known list of peers. """ 215 | if peerid in self.peers: 216 | del self.peers[ peerid ] 217 | 218 | 219 | 220 | #-------------------------------------------------------------------------- 221 | def addpeerat( self, loc, peerid, host, port ): 222 | #-------------------------------------------------------------------------- 223 | """ Inserts a peer's information at a specific position in the 224 | list of peers. The functions addpeerat, getpeerat, and removepeerat 225 | should not be used concurrently with addpeer, getpeer, and/or 226 | removepeer. 227 | 228 | """ 229 | self.peers[ loc ] = (peerid, host, int(port)) 230 | 231 | 232 | 233 | #-------------------------------------------------------------------------- 234 | def getpeerat( self, loc ): 235 | #-------------------------------------------------------------------------- 236 | if loc not in self.peers: 237 | return None 238 | return self.peers[ loc ] 239 | 240 | 241 | 242 | #-------------------------------------------------------------------------- 243 | def removepeerat( self, loc ): 244 | #-------------------------------------------------------------------------- 245 | removepeer( self, loc ) 246 | 247 | 248 | 249 | #-------------------------------------------------------------------------- 250 | def getpeerids( self ): 251 | #-------------------------------------------------------------------------- 252 | """ Return a list of all known peer id's. """ 253 | return self.peers.keys() 254 | 255 | 256 | 257 | #-------------------------------------------------------------------------- 258 | def numberofpeers( self ): 259 | #-------------------------------------------------------------------------- 260 | """ Return the number of known peer's. """ 261 | return len(self.peers) 262 | 263 | 264 | 265 | #-------------------------------------------------------------------------- 266 | def maxpeersreached( self ): 267 | #-------------------------------------------------------------------------- 268 | """ Returns whether the maximum limit of names has been added to the 269 | list of known peers. Always returns True if maxpeers is set to 270 | 0. 271 | 272 | """ 273 | assert self.maxpeers == 0 or len(self.peers) <= self.maxpeers 274 | return self.maxpeers > 0 and len(self.peers) == self.maxpeers 275 | 276 | 277 | 278 | #-------------------------------------------------------------------------- 279 | def makeserversocket( self, port, backlog=5 ): 280 | #-------------------------------------------------------------------------- 281 | """ Constructs and prepares a server socket listening on the given 282 | port. 283 | 284 | """ 285 | s = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) 286 | s.setsockopt( socket.SOL_SOCKET, socket.SO_REUSEADDR, 1 ) 287 | s.bind( ( '', port ) ) 288 | s.listen( backlog ) 289 | return s 290 | 291 | 292 | 293 | #-------------------------------------------------------------------------- 294 | def sendtopeer( self, peerid, msgtype, msgdata, waitreply=True ): 295 | #-------------------------------------------------------------------------- 296 | """ 297 | sendtopeer( peer id, message type, message data, wait for a reply ) 298 | -> [ ( reply type, reply data ), ... ] 299 | 300 | Send a message to the identified peer. In order to decide how to 301 | send the message, the router handler for this peer will be called. 302 | If no router function has been registered, it will not work. The 303 | router function should provide the next immediate peer to whom the 304 | message should be forwarded. The peer's reply, if it is expected, 305 | will be returned. 306 | 307 | Returns None if the message could not be routed. 308 | """ 309 | 310 | if self.router: 311 | nextpid, host, port = self.router( peerid ) 312 | if not self.router or not nextpid: 313 | self.__debug( 'Unable to route %s to %s' % (msgtype, peerid) ) 314 | return None 315 | #host,port = self.peers[nextpid] 316 | return self.connectandsend( host, port, msgtype, msgdata, 317 | pid=nextpid, 318 | waitreply=waitreply ) 319 | 320 | 321 | 322 | #-------------------------------------------------------------------------- 323 | def connectandsend( self, host, port, msgtype, msgdata, 324 | pid=None, waitreply=True ): 325 | #-------------------------------------------------------------------------- 326 | """ 327 | connectandsend( host, port, message type, message data, peer id, 328 | wait for a reply ) -> [ ( reply type, reply data ), ... ] 329 | 330 | Connects and sends a message to the specified host:port. The host's 331 | reply, if expected, will be returned as a list of tuples. 332 | 333 | """ 334 | msgreply = [] 335 | try: 336 | peerconn = BTPeerConnection( pid, host, port, debug=self.debug ) 337 | peerconn.senddata( msgtype, msgdata ) 338 | self.__debug( 'Sent %s: %s' % (pid, msgtype) ) 339 | 340 | if waitreply: 341 | onereply = peerconn.recvdata() 342 | while (onereply != (None,None)): 343 | msgreply.append( onereply ) 344 | self.__debug( 'Got reply %s: %s' 345 | % ( pid, str(msgreply) ) ) 346 | onereply = peerconn.recvdata() 347 | peerconn.close() 348 | except KeyboardInterrupt: 349 | raise 350 | except: 351 | if self.debug: 352 | traceback.print_exc() 353 | 354 | return msgreply 355 | 356 | # end connectsend method 357 | 358 | 359 | 360 | #-------------------------------------------------------------------------- 361 | def checklivepeers( self ): 362 | #-------------------------------------------------------------------------- 363 | """ Attempts to ping all currently known peers in order to ensure that 364 | they are still active. Removes any from the peer list that do 365 | not reply. This function can be used as a simple stabilizer. 366 | 367 | """ 368 | 369 | 370 | todelete = [] 371 | for pid in self.peers: 372 | isconnected = False 373 | try: 374 | self.__debug( 'Check live %s' % pid ) 375 | host,port = self.peers[pid] 376 | peerconn = BTPeerConnection( pid, host, port, debug=self.debug ) 377 | peerconn.senddata( 'PING', '' ) 378 | isconnected = True 379 | except: 380 | todelete.append( pid ) 381 | if isconnected: 382 | peerconn.close() 383 | 384 | self.peerlock.acquire() 385 | try: 386 | for pid in todelete: 387 | if pid in self.peers: del self.peers[pid] 388 | finally: 389 | self.peerlock.release() 390 | 391 | #self.__debug("Cancel check") 392 | # end checklivepeers method 393 | 394 | 395 | 396 | #-------------------------------------------------------------------------- 397 | def mainloop( self ): 398 | #-------------------------------------------------------------------------- 399 | s = self.makeserversocket( self.serverport ) 400 | s.settimeout(2) 401 | self.__debug( 'Server started: %s (%s:%d)' 402 | % ( self.myid, self.serverhost, self.serverport ) ) 403 | 404 | while not self.shutdown: 405 | try: 406 | self.__debug( 'Listening for connections...' ) 407 | clientsock, clientaddr = s.accept() 408 | clientsock.settimeout(None) 409 | 410 | t = threading.Thread( target = self.__handlepeer, 411 | args = [ clientsock ] ) 412 | t.start() 413 | except KeyboardInterrupt: 414 | print 'KeyboardInterrupt: stopping mainloop' 415 | self.shutdown = True 416 | continue 417 | except: 418 | if self.debug: 419 | traceback.print_exc() 420 | continue 421 | 422 | # end while loop 423 | self.__debug( 'Main loop exiting' ) 424 | 425 | s.close() 426 | 427 | # end mainloop method 428 | 429 | # end BTPeer class 430 | 431 | 432 | 433 | 434 | # ********************************************************** 435 | 436 | 437 | 438 | 439 | class BTPeerConnection: 440 | 441 | #-------------------------------------------------------------------------- 442 | def __init__( self, peerid, host, port, sock=None, debug=False ): 443 | #-------------------------------------------------------------------------- 444 | # any exceptions thrown upwards 445 | 446 | self.id = peerid 447 | self.debug = debug 448 | 449 | if not sock: 450 | self.s = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) 451 | self.s.connect( ( host, int(port) ) ) 452 | else: 453 | self.s = sock 454 | 455 | self.sd = self.s.makefile( 'rw', 0 ) 456 | 457 | 458 | #-------------------------------------------------------------------------- 459 | def __makemsg( self, msgtype, msgdata ): 460 | #-------------------------------------------------------------------------- 461 | msglen = len(msgdata) 462 | msg = struct.pack( "!4sL%ds" % msglen, msgtype, msglen, msgdata ) 463 | return msg 464 | 465 | 466 | #-------------------------------------------------------------------------- 467 | def __debug( self, msg ): 468 | #-------------------------------------------------------------------------- 469 | if self.debug: 470 | btdebug( msg ) 471 | 472 | 473 | #-------------------------------------------------------------------------- 474 | def senddata( self, msgtype, msgdata ): 475 | #-------------------------------------------------------------------------- 476 | """ 477 | senddata( message type, message data ) -> boolean status 478 | 479 | Send a message through a peer connection. Returns True on success 480 | or False if there was an error. 481 | """ 482 | 483 | try: 484 | msg = self.__makemsg( msgtype, msgdata ) 485 | self.sd.write( msg ) 486 | self.sd.flush() 487 | except KeyboardInterrupt: 488 | raise 489 | except: 490 | if self.debug: 491 | traceback.print_exc() 492 | return False 493 | return True 494 | 495 | 496 | #-------------------------------------------------------------------------- 497 | def recvdata( self ): 498 | #-------------------------------------------------------------------------- 499 | """ 500 | recvdata() -> (msgtype, msgdata) 501 | 502 | Receive a message from a peer connection. Returns (None, None) 503 | if there was any error. 504 | """ 505 | 506 | try: 507 | msgtype = self.sd.read( 4 ) 508 | if not msgtype: return (None, None) 509 | 510 | lenstr = self.sd.read( 4 ) 511 | msglen = int(struct.unpack( "!L", lenstr )[0]) 512 | msg = "" 513 | 514 | while len(msg) != msglen: 515 | data = self.sd.read( min(2048, msglen - len(msg)) ) 516 | if not len(data): 517 | break 518 | msg += data 519 | 520 | if len(msg) != msglen: 521 | return (None, None) 522 | 523 | except KeyboardInterrupt: 524 | raise 525 | except: 526 | if self.debug: 527 | traceback.print_exc() 528 | return (None, None) 529 | 530 | return ( msgtype, msg ) 531 | 532 | # end recvdata method 533 | 534 | 535 | #-------------------------------------------------------------------------- 536 | def close( self ): 537 | #-------------------------------------------------------------------------- 538 | """ 539 | close() 540 | 541 | Close the peer connection. The send and recv methods will not work 542 | after this call. 543 | """ 544 | 545 | self.s.close() 546 | self.s = None 547 | self.sd = None 548 | 549 | 550 | #-------------------------------------------------------------------------- 551 | def __str__( self ): 552 | #-------------------------------------------------------------------------- 553 | return "|%s|" % peerid 554 | 555 | 556 | 557 | 558 | -------------------------------------------------------------------------------- /construction-0/btringoram.py: -------------------------------------------------------------------------------- 1 | from btcrypto import * 2 | import itertools 3 | import time 4 | import traceback 5 | import sys 6 | 7 | class BtRingORAM: 8 | 9 | def __init__( self, realnumber, realpath, dummynumber, dummypath, leavesnumber, evictionrate, blocksize ): 10 | #-------------------------------------------------------------------------- 11 | """ Initiation of a BtRingORAM for our construction-0 """ 12 | 13 | self.debug = 0 #flag for debugging 14 | self.positionmap = {} # dataid --> tag, level, number 15 | self.peermap = {} # available peers: o-ram id --> peerid 16 | self.peermapreverse = {} # reverse peermap: peerid --> o-ram id 17 | self.peerdata = {} # {peertag:{count:0, rvalid:[], dvalid:[], dataid:[dataid1, dataid2]},...} 18 | self.stashrealdata = {} #Real data: dataid --> datacontent 19 | self.stashmap = {} #dataid: --> datatag (new assigned tag)} 20 | self.tagmap = {} #datatag --> number (maximum is Z) 21 | self.Z = realnumber 22 | self.S = dummynumber 23 | self.A = evictionrate 24 | self.N = leavesnumber #2**N is number of leaves 25 | self.key = generateKey(32) #Generate a random key for btringoram 26 | self.blocksize = blocksize 27 | self.dummypath = dummypath 28 | self.realpath = realpath 29 | self.dummydata = "" 30 | 31 | #initiation 32 | self.__init_peermap(self.N) 33 | self.__init_tagmap(self.N) 34 | self.__initdummydata() 35 | self.btaes = AESCipher(self.key) 36 | self.G = 0 #global counter for eviction path 37 | self.Acount = 0 #global counter for eviction 38 | self.evictionpaths = self.__initevictionpaths() #eviction paths following reverse lexi order 39 | 40 | # peermap: {peertag:{count:0, rvalid:[], dvalid:[], data:[dataid1, dataid2]},...} 41 | def __initpeerdata ( self, peertag ): 42 | #-------------------------------------------------------------------------- 43 | """ Reset peerrdata, and push real data in stash to the new peer 44 | """ 45 | self.__resetpeerdata(peertag) 46 | #self.__debug(str(self.peerdata)) 47 | return self.__pushstashtopeer(peertag) 48 | 49 | 50 | def __initdummydata ( self ): 51 | #-------------------------------------------------------------------------- 52 | """ Reset peerrdata, and push real data in stash to the new peer 53 | """ 54 | #read dummy data 55 | fd = file(self.dummypath + "/dummy.txt", 'r') 56 | self.dummydata = '' 57 | while True: 58 | filedata = fd.read(2048) 59 | if not len(filedata): 60 | break 61 | self.dummydata += filedata 62 | fd.close() 63 | 64 | def join ( self, peerid ): 65 | #-------------------------------------------------------------------------- 66 | """ A new peer joins the network, returns the data pushed to the peer including real data and dummy data 67 | """ 68 | print "function join" 69 | #peerid: IP:port 70 | peertag = "" 71 | fullflag = True 72 | if peerid is None: 73 | self.__debug('Peerid is None.') 74 | return None 75 | 76 | for i in self.bitstrings: 77 | if self.peermap[i] is None: 78 | peertag = i 79 | self.peermap[i] = peerid 80 | self.peermapreverse[peerid] = i 81 | fullflag = False 82 | break 83 | #return True 84 | if fullflag: 85 | self.__debug('ORAM tree is full.') 86 | return None 87 | #Now join btringoram, dummy blocks will be returned; later real blocks can be returned 88 | data = [] #data = [data1, data2, ...] 89 | #data = self.__generatedummy(self.dummypath, self.Z + self.S) 90 | data = self.__initpeerdata(peertag) 91 | return data 92 | 93 | def uploaddata (self, dataid, datacontent): 94 | #-------------------------------------------------------------------------- 95 | """ Upload data with id and content. 96 | """ 97 | print "function uploaddata" 98 | if len(datacontent) != self.blocksize: 99 | self.__debug("Data size is not %s." % self.blocksize) 100 | return None 101 | datatag = self.__generaterandomtag() 102 | self.__updatestashrealdata(dataid, datacontent) 103 | self.__updatestashmap(dataid, datatag) 104 | self.__addtagmap(datatag) 105 | 106 | taglist = {} #eviction --> pathtag 107 | taglist["eviction"] = None 108 | self.Acount += 1 109 | pathtag = "" 110 | if self.Acount >= self.A: 111 | pathtag = self.evictionpaths[self.G] 112 | #self.eviction(pathtag, data) 113 | taglist["eviction"] = pathtag 114 | self.G += 1 115 | if self.G >= len(self.evictionpaths): 116 | self.G = 0 117 | self.Acount = 0 118 | #print self.positionmap 119 | print taglist 120 | return taglist 121 | 122 | def readdata (self, dataid): 123 | #-------------------------------------------------------------------------- 124 | """ Read data based on dataid. The return value is a list of pathtag for eviction, peers for earlyshuffle, data in stash, 125 | or which peer and number should read 126 | """ 127 | print "function readdata" 128 | taglist = {} #eviction: peertag, earlyshuffle: [level, ...], stash: dataid, realdatapeer: peerid, peerid: number 129 | realflag = True 130 | datatag = "" 131 | leveltag = "" 132 | taglist["eviction"] = None 133 | taglist["realdatapeer"] = None 134 | taglist["earlyshuffle"] = [] 135 | if dataid in self.stashmap: 136 | taglist["stash"] = self.stashrealdata[dataid] 137 | datatag = self.stashmap[dataid] 138 | #print ("dataid: " + dataid + " datatag: " + datatag) 139 | newdatatag = self.__generaterandomtag() 140 | self.__updatestashmap(dataid, newdatatag) 141 | self.__removetagmap(datatag) 142 | self.__addtagmap(newdatatag) 143 | realflag = False 144 | else: 145 | taglist["stash"] = None 146 | datatag = self.positionmap[dataid][0] 147 | leveltag = self.positionmap[dataid][1] 148 | 149 | for i in range(len(datatag)+1): 150 | if i == len(datatag): 151 | level = "R" 152 | else: 153 | level = datatag[:i+1] 154 | if (level == leveltag) and realflag: 155 | datanumber = self.positionmap[dataid][2] 156 | taglist[self.peermap[level]] = datanumber 157 | self.peerdata[level]["rvalid"].remove(datanumber) 158 | 159 | 160 | self.peerdata[level]["count"] += 1 161 | if self.peerdata[level]["count"] >= self.S: 162 | taglist["earlyshuffle"].append(level) 163 | 164 | self.__removetagmap(self.positionmap[dataid][0]) 165 | ###To do 166 | #Waiting for response data to update stashmap, stashrealdata and tagmap 167 | taglist["realdatapeer"] = self.peermap[level] 168 | newdatatag = self.__generaterandomtag() 169 | #self.__updatestashrealdata(dataid, datacontent) 170 | self.__updatestashmap(dataid, newdatatag) 171 | self.__addtagmap(newdatatag) 172 | self.__removepositionmap(dataid) 173 | #remove positionmap, de-valid peerdata, push to stashrealdata & stashmap 174 | else: 175 | #Incomplete tree check 176 | if self.peermap[level] is not None: 177 | randomdummy = random.choice(self.peerdata[level]["dvalid"]) 178 | self.peerdata[level]["dvalid"].remove(randomdummy) 179 | self.peerdata[level]["count"] += 1 180 | if self.peerdata[level]["count"] >= self.S: 181 | taglist["earlyshuffle"].append(level) 182 | taglist[self.peermap[level]] = randomdummy 183 | 184 | self.Acount += 1 185 | pathtag = "" 186 | if self.Acount >= self.A: 187 | pathtag = self.evictionpaths[self.G] 188 | #self.eviction(pathtag, data) 189 | taglist["eviction"] = pathtag 190 | self.G += 1 191 | if self.G >= len(self.evictionpaths): 192 | self.G = 0 193 | self.Acount = 0 194 | print taglist 195 | return taglist 196 | 197 | def earlyshuffle ( self, peertag, data ): 198 | #-------------------------------------------------------------------------- 199 | """ Shuffle data in the peer. 200 | """ 201 | #read 202 | print "function earlyshuffle peertag: %s" % peertag 203 | print "stashmap number before earlyshuffle: %s" % len(self.stashmap.keys()) 204 | print self.peerdata[peertag] 205 | self.__pullpeertostash(peertag, data) 206 | #write 207 | resp = self.__pushstashtopeer(peertag) 208 | print "stashmap number after earlyshuffle: %s" % len(self.stashmap.keys()) 209 | return resp 210 | 211 | 212 | def eviction ( self, pathtag, data ): 213 | #-------------------------------------------------------------------------- 214 | """ Eviction for a path based on pathtag with its data. 215 | """ 216 | #pathtag: "111" 217 | #data: peertag --> [data1, data2, ...] 218 | #resp: peertag --> [data1, data2, ...] 219 | print "function eviction pathtag: %s" % pathtag 220 | print "stashmap number before eviction: %s" % len(self.stashmap.keys()) 221 | #read 222 | for i in data: 223 | peertag = i 224 | self.__pullpeertostash(peertag, data[i]) 225 | 226 | #write 227 | resp = {} 228 | for j in range(len(pathtag)): 229 | peertag = pathtag[:len(pathtag)-j] 230 | #Incomplete tree check 231 | if self.peermap[peertag] is not None: 232 | resp[peertag] = self.__pushstashtopeer(peertag) 233 | resp["R"] = self.__pushstashtopeer("R") 234 | print "function eviction pathtag: %s" % pathtag 235 | print "stashmap number after eviction: %s" % len(self.stashmap.keys()) 236 | print self.stashmap 237 | return resp 238 | 239 | def __pullpeertostash ( self, peertag, data ): 240 | #-------------------------------------------------------------------------- 241 | """ Pull data from a peer to stash, preparing for earlyshuffle or eviction. 242 | """ 243 | #data: [data1, data2, ...] 244 | #Pull valid real data from peertag to stash 245 | print "function __pullpeertostash" 246 | for i in self.peerdata[peertag]["rvalid"]: 247 | dataid = self.peerdata[peertag]["dataid"][i] 248 | self.stashrealdata[dataid] = data[i] 249 | #in stash not in positionmap; but in peerdata 250 | datatag = self.positionmap[dataid][0] 251 | #Fixed bug: Only reading real data from stash or peers needs a new datatag, earlyshuffle or eviction does not require a block to change to a new tag 252 | #newdatatag = self.__generaterandomtag() 253 | #self.__updatestashmap(dataid, newdatatag) 254 | self.__updatestashmap(dataid, datatag) 255 | del self.positionmap[dataid] 256 | 257 | 258 | def __pushstashtopeer ( self, peertag ): 259 | #-------------------------------------------------------------------------- 260 | """ Push real data in stash to a peer (peertag) 261 | """ 262 | #Find real data in stash fit for peertag 263 | print "function __pushstashtopeer" 264 | #print peertag 265 | count = 0 266 | tmpdataid = [] 267 | respdata = [] #[data1, data2, ...] 268 | permutation = [] 269 | for i in range(self.Z+self.S): 270 | tmpdataid.append("dummy") 271 | #sorted(self.stashmap) 272 | for i in self.stashmap: 273 | #Fixed bug: do not use is, but == 274 | if (peertag == "R") or (self.stashmap[i][:len(peertag)] == peertag): 275 | tmpdataid[count] = i 276 | #del self.stashmap[i] 277 | count += 1 278 | if count >= self.Z: 279 | break 280 | #Permutate real data and dummy data 281 | permutation = [i for i in range(self.Z+self.S)] 282 | shuffle(permutation) 283 | self.__resetpeerdata(peertag) 284 | respdata = ["" for i in range(self.Z+self.S)] 285 | #Update peerdata and set respdata based on its permutated order 286 | print "stashmap" 287 | print self.stashmap 288 | for i in range(len(permutation)): 289 | if tmpdataid[i] == "dummy": 290 | singledummy = self.__generatedummy(self.dummypath, 1) 291 | respdata[permutation[i]] = singledummy[0] 292 | self.peerdata[peertag]["dvalid"].append(permutation[i]) 293 | self.peerdata[peertag]["dataid"][permutation[i]] = "dummy" 294 | else: 295 | #Re-encrypt real data not dummy data 296 | tmpdata = self.btaes.decrypt(self.stashrealdata[tmpdataid[i]]) 297 | respdata[permutation[i]] = self.btaes.encrypt(tmpdata) 298 | self.peerdata[peertag]["rvalid"].append(permutation[i]) 299 | self.peerdata[peertag]["dataid"][permutation[i]] = tmpdataid[i] 300 | 301 | self.positionmap[tmpdataid[i]] = [self.stashmap[tmpdataid[i]], peertag, permutation[i]] 302 | del self.stashmap[tmpdataid[i]] 303 | del self.stashrealdata[tmpdataid[i]] 304 | 305 | print "push to peertag: %s. rvalid %s" % (peertag, self.peerdata[peertag]["dataid"]) 306 | return respdata 307 | 308 | def __initevictionpaths ( self ): 309 | #-------------------------------------------------------------------------- 310 | """ Choose a path for eviction based on reverse-lexi order, e.g., 00, 10, 01, 11 311 | """ 312 | tags = self.tagmap.keys() 313 | paths = {} 314 | for i in range(len(tags)): 315 | paths[tags[i][::-1]] = tags[i] 316 | reverselexiorderpaths = [paths[i] for i in sorted(paths)] 317 | return reverselexiorderpaths 318 | 319 | def __resetpeerdata ( self, peertag ): 320 | #-------------------------------------------------------------------------- 321 | """ Reset peerdata for a peer. 322 | """ 323 | self.peerdata[peertag] = {} 324 | self.peerdata[peertag]["count"] = 0 325 | self.peerdata[peertag]["rvalid"] = [] 326 | self.peerdata[peertag]["dvalid"] = [] 327 | self.peerdata[peertag]["dataid"] = ["" for i in range(self.Z+self.S)] 328 | 329 | def __removepositionmap (self, dataid): 330 | #-------------------------------------------------------------------------- 331 | """ Remove the item of dataid in positionmap. 332 | """ 333 | del self.positionmap[dataid] 334 | 335 | def __updatestashrealdata (self, dataid, datacontent): 336 | #-------------------------------------------------------------------------- 337 | """ Add real data to stash. 338 | """ 339 | self.stashrealdata[dataid] = self.btaes.encrypt(datacontent) 340 | #self.__debug(self.stashrealdata) 341 | 342 | def __removestashrealdata (self, dataid): 343 | #-------------------------------------------------------------------------- 344 | """ Remove data from stash. 345 | """ 346 | del self.stashrealdata[dataid] 347 | 348 | def __updatestashmap (self, dataid, datatag): 349 | #-------------------------------------------------------------------------- 350 | """ Map a datatag to a data 351 | """ 352 | self.stashmap[dataid] = datatag 353 | #self.__debug(self.stashmap) 354 | 355 | def __removestashmap (self, dataid): 356 | #-------------------------------------------------------------------------- 357 | """ Remove a dataid/datatag mapping. 358 | """ 359 | del self.stashmap[dataid] 360 | 361 | def __addtagmap (self, datatag): 362 | #-------------------------------------------------------------------------- 363 | """ Increase the used number of a datatag 364 | """ 365 | self.__debug("tagmap") 366 | #self.__debug("datatag: " + str(datatag)) 367 | self.tagmap[datatag] += 1 368 | self.__debug(self.tagmap) 369 | 370 | def __removetagmap (self, datatag): 371 | #-------------------------------------------------------------------------- 372 | """ Decrease the used number of a datatag 373 | """ 374 | self.tagmap[datatag] -= 1 375 | 376 | def __debug (self, msg): 377 | #-------------------------------------------------------------------------- 378 | """ Print debug information. 379 | """ 380 | if self.debug: 381 | print msg 382 | 383 | #-------------------------------------------------------------------------- 384 | def __generatebitstrings( self, number ): 385 | #-------------------------------------------------------------------------- 386 | """ Generate bitstrings for a number: 2 --> 0, 1, 00, 01, 10, 11 387 | """ 388 | bitstrings = ['R'] 389 | for i in range( 1, number+1 ): 390 | for j in itertools.product( '01', repeat=i ): 391 | bits = [''.join(j)] #j: ('0', '0') 392 | bitstrings += bits 393 | return bitstrings 394 | 395 | def __init_peermap( self, bitstringlength ): 396 | """ Generate bitstrings as keys for peermap 397 | """ 398 | #initiation for peermap 399 | self.bitstrings = self.__generatebitstrings(bitstringlength) 400 | for bits in self.bitstrings: 401 | self.peermap[bits] = None 402 | 403 | def __init_tagmap( self, number): 404 | #-------------------------------------------------------------------------- 405 | """ Generate bits as keys for tagmap 406 | """ 407 | #initiation for tagmap 408 | for j in itertools.product( '01', repeat=number ): 409 | bits = ''.join(j) 410 | self.tagmap[bits] = 0 411 | 412 | def __generaterandomtag ( self ): 413 | #-------------------------------------------------------------------------- 414 | """ Generate a random tag for real data not dummy data 415 | """ 416 | #Generate a random tag for real data not dummy data 417 | tags = [] 418 | for i in self.tagmap: 419 | tags.append(i) 420 | if len(tags) == 0: 421 | return None 422 | return generaterandomchoice(tags) 423 | 424 | def __generatedummy( self, dummypath, number ): 425 | #-------------------------------------------------------------------------- 426 | """ Generate a dummy data list based on number 427 | """ 428 | 429 | data = [] 430 | for i in range(0, number): 431 | data.append(self.btaes.encrypt(self.dummydata)) 432 | #self.__debug(data) 433 | return data -------------------------------------------------------------------------------- /construction-0/btserver0.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # btgui.py by Nadeem Abdul Hamid 4 | 5 | """ 6 | Module implementing simple BerryTella GUI for a simple p2p network. 7 | """ 8 | 9 | 10 | import sys 11 | import threading 12 | 13 | from random import * 14 | 15 | from btserverfiler import * 16 | 17 | 18 | class BTGui: 19 | def __init__( self, firstpeer, hops=2, maxpeers=5, serverport=5678, serverhost=None, master=None ): 20 | self.btpeer = FilerPeer( maxpeers, serverport, serverhost ) 21 | 22 | 23 | host,port = firstpeer.split(':') 24 | self.btpeer.buildpeers( host, int(port), hops=hops ) 25 | #self.updatePeerList() 26 | 27 | t = threading.Thread( target = self.btpeer.mainloop, args = [] ) 28 | t.start() 29 | 30 | self.btpeer.startstabilizer( self.btpeer.checklivepeers, 3 ) 31 | 32 | 33 | def main(): 34 | if len(sys.argv) < 5: 35 | print "Syntax: %s server-host server-port max-peers peer-ip:port" % sys.argv[0] 36 | sys.exit(-1) 37 | if sys.argv[1] != "0": 38 | serverhost = sys.argv[1] 39 | else: 40 | serverhost = None 41 | serverport = int(sys.argv[2]) 42 | maxpeers = sys.argv[3] 43 | peerid = sys.argv[4] 44 | app = BTGui( firstpeer=peerid, maxpeers=maxpeers, serverport=serverport, serverhost=serverhost ) 45 | 46 | 47 | # setup and run app 48 | if __name__=='__main__': 49 | main() 50 | -------------------------------------------------------------------------------- /construction-0/createfile.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import sys 4 | 5 | N = int(sys.argv[1]) 6 | 7 | infile = open('dummy.txt', 'r') 8 | indata = infile.read() 9 | infile.close() 10 | 11 | outdata = "" 12 | for i in range(N): 13 | outdata += indata 14 | 15 | outfilename = "dummy" + str(N) + ".txt" 16 | outfile = open(outfilename, "w") 17 | outfile.write(outdata) 18 | outfile.close() -------------------------------------------------------------------------------- /construction-0/dummy.txt: -------------------------------------------------------------------------------- 1 | reseminate 2 | tongueflower 3 | Overlander 4 | Centrosoyus 5 | teleseismic 6 | postmasterlike 7 | identifiableness 8 | dysmnesia 9 | cutleress 10 | occupation 11 | scribbler 12 | forbore 13 | ossuary 14 | waitress 15 | stylistical 16 | overcivilization 17 | rumpadder 18 | Jock 19 | spray 20 | Aeluroidea 21 | pseudosymmetric 22 | topalgia 23 | uncartooned 24 | streyne 25 | closestool 26 | cushioned 27 | haddocker 28 | Sitophilus 29 | overtutor 30 | demanganize 31 | unprefigured 32 | feere 33 | needlessness 34 | afront 35 | splendaciously 36 | nonvascular 37 | heterologically 38 | Susanna 39 | voraciousness 40 | boatbuilder 41 | catafalque 42 | equilibrium 43 | governorate 44 | bourbonize 45 | meteorization 46 | unpulvinate 47 | unsepulchral 48 | preabsorbent 49 | vetchy 50 | nonuser 51 | roisterous 52 | owler 53 | undiuretic 54 | Ansarie 55 | ricinic 56 | undercapitalization 57 | spun 58 | odontocete 59 | detergence 60 | landladydom 61 | Homoousian 62 | distome 63 | relatinization 64 | teachableness 65 | electrization 66 | foxship 67 | concurrent 68 | retronasal 69 | microsommite 70 | cyrtoceratite 71 | aphilanthropy 72 | cladine 73 | thyroidotomy 74 | domestic 75 | yether 76 | anteroinferior 77 | seizin 78 | circumintestinal 79 | corm 80 | Kim 81 | newsprint 82 | archcozener 83 | oxydiact 84 | recant 85 | recrystallize 86 | reboundable 87 | forbidder 88 | hunkies 89 | Furnariidae 90 | panstereorama 91 | moderant 92 | tameheartedness 93 | tameheartedna 94 | -------------------------------------------------------------------------------- /construction-0/kill.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | 3 | def subprocess_cmd(command): 4 | process = subprocess.Popen(command,stdout=subprocess.PIPE, shell=True) 5 | proc_stdout = process.communicate()[0].strip() 6 | print proc_stdout 7 | return proc_stdout 8 | 9 | cmd = "ps -x | grep python" 10 | resp = subprocess_cmd(cmd) 11 | lines = resp.split("\n") 12 | #print lines 13 | pids = "" 14 | for i in lines: 15 | print i 16 | if "ttys" in i: 17 | pid, _ = i.split("ttys") 18 | elif "pts" in i: 19 | pid, _ = i.split("pts") 20 | elif "?" in i: 21 | pid, _ = i.split("?") 22 | pids += pid 23 | 24 | #for Mac 25 | cmd = "kill " + pids 26 | 27 | #for Linux 28 | #cmd = "kill -9 " + pids 29 | 30 | print cmd 31 | resp = subprocess_cmd(cmd) 32 | -------------------------------------------------------------------------------- /construction-0/shell.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import socket 3 | import struct 4 | import threading 5 | import time 6 | import traceback 7 | import sys 8 | 9 | def subprocess_cmd(command): 10 | process = subprocess.Popen(command,stdout=subprocess.PIPE, shell=True) 11 | proc_stdout = process.communicate()[0].strip() 12 | print proc_stdout 13 | 14 | def obtain_host(): 15 | s = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) 16 | s.connect( ( "www.google.com", 80 ) ) 17 | serverhost = s.getsockname()[0] 18 | #print "server host: %s" % serverhost 19 | s.close() 20 | return serverhost 21 | 22 | cmd = "" 23 | N = int(sys.argv[1]) 24 | M = (2**(N+1) -1) - 1 25 | #serverhost = obtain_host() 26 | trackerid = "127.0.0.1:7090" 27 | serverhost = "127.0.0.1" 28 | #trackerid = "10.1.1.2:7090" 29 | #serverhost = "10.1.1.3" 30 | for i in range(0, M): 31 | cmd = cmd + "python btclient0.py -c 1 " + serverhost + " "+ str(10000+i) + " 0 " + trackerid + "& \n" 32 | 33 | print cmd 34 | subprocess_cmd(cmd) 35 | -------------------------------------------------------------------------------- /construction-1/README.md: -------------------------------------------------------------------------------- 1 | ### Requirement: python3 python-crypto 2 | 3 | ### Set up tracker: 4 | #### python3 btserver0.py tracker-host tracker-port max-peers default-ip:port 5 | $ python3 btserver0.py 127.0.0.1 7090 0 0.0.0.0:8090 6 | 7 | ### Set up 2^(N+1) - 1 nodes: 8 | $ python3 auto.py N 9 | 10 | ### Client requests to upload/fetch blocks: 11 | #### python btclient1.py -c 1 peer-host peer-port max-peers tracker-ip:port" 12 | $ python3 btclient2.py -c 1 127.0.0.1 20000 0 127.0.0.1:7090 13 | 14 | ### Stop running nodes (kill all running python processes): 15 | $ python kill.py 16 | -------------------------------------------------------------------------------- /construction-1/auto.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import socket 3 | import struct 4 | import threading 5 | import time 6 | import traceback 7 | import sys 8 | 9 | def debug (msg): 10 | #-------------------------------------------------------------------------- 11 | """ Print debug information. 12 | """ 13 | print(msg) 14 | 15 | def subprocess_cmd(command): 16 | process = subprocess.Popen(command,stdout=subprocess.PIPE, shell=True) 17 | proc_stdout = process.communicate()[0].strip() 18 | debug( proc_stdout) 19 | 20 | def obtain_host(): 21 | s = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) 22 | s.connect( ( "www.google.com", 80 ) ) 23 | serverhost = s.getsockname()[0] 24 | debug( "server host: %s" % serverhost) 25 | #print "server host: %s" % serverhost 26 | s.close() 27 | return serverhost 28 | 29 | cmd = "" 30 | N = int(sys.argv[1]) 31 | M = 2**(N+1) - 2 32 | #serverhost = obtain_host() 33 | serverhost = "127.0.0.1" 34 | trackerid = "127.0.0.1:7090" 35 | for i in range(0, M): 36 | cmd = cmd + " sleep 0.01; python3 btclient0.py -c 1 " + serverhost + " "+ str(10000+i) + " 0 " + trackerid + "& " 37 | 38 | debug( cmd) 39 | subprocess_cmd(cmd) 40 | -------------------------------------------------------------------------------- /construction-1/btclient0.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | Module implementing simple BerryTella GUI for a simple p2p network. 5 | """ 6 | 7 | 8 | import sys 9 | import threading 10 | 11 | #from Tkinter import * 12 | from random import * 13 | 14 | from btfiler import * 15 | 16 | 17 | 18 | class BtClient: 19 | def __init__( self, firstpeer, hops=2, maxpeers=5, serverport=5678, serverhost=None, master=None ): 20 | 21 | self.btpeer = FilerPeer( maxpeers, serverport, serverhost ) 22 | 23 | host,port = firstpeer.split(':') 24 | #self.btpeer.buildpeers( host, int(port), hops=hops ) 25 | #self.updatePeerList() 26 | 27 | t = threading.Thread( target = self.btpeer.mainloop, args = [] ) 28 | t.start() 29 | #Cancel ping check 30 | self.btpeer.startstabilizer( self.btpeer.checklivepeers, 3 ) 31 | 32 | 33 | def naiveinit_1(self, peerid): 34 | #response = self.btpeer.sendtopeer( peerid, NAIVEINIT, self.btpeer.myid ) 35 | print("function naiveinit_1") 36 | self.btdebug(peerid) 37 | host,port = peerid.split(':') 38 | resp = self.btpeer.connectandsend( host, port, NAIVEINIT1, self.btpeer.myid ) 39 | print("self.btpeer.myid", self.btpeer.myid) 40 | #print peerid + NAIVEINIT + self.btpeer.myid 41 | #print str(resp) 42 | if len(resp) > 0: 43 | data = resp[0][1] 44 | self.btpeer.bucketdata = self.btpeer.btitpiroram.convertfromstringtopointlist(data) 45 | #number = self.btpeer.bucketdata[0] 46 | #del self.btpeer.bucketdata[0] 47 | #print("bucketdata", str(self.btpeer.bucketdata)) 48 | 49 | def uploaddata_1( self, peerid, dataid ): 50 | host,port = peerid.split(':') 51 | senddata = dataid 52 | resp = self.btpeer.connectandsend(host, port, UPLOADDATA1, senddata) 53 | #data = resp[0][1] 54 | #self.btdebug( resp) 55 | data = resp[0][1] 56 | transactionid, uploadcircuitpeers = str(data).split('<<<') 57 | self.btpeer.uploadcircuitpeers[transactionid] = uploadcircuitpeers.split(">>>") 58 | 59 | #Generate a block, prepare points 60 | forcircuitpoints = {} 61 | for i in self.btpeer.uploadcircuitpeers[transactionid]: 62 | forcircuitpoints[i] = [] 63 | 64 | realpoints = [] 65 | realdatanumber = [] 66 | for i in range(self.btpeer.btitpiroram.pointsnum): 67 | realdatanumber.append(int(dataid.split("data")[1])) 68 | 69 | #realdatanumber = 1 #mock number for realdata 70 | #onepoint = btitpiroram.usedcurve.G * datapoint 71 | #oneblock = btitpiroram.convertfrompointtostring(onepoint) 72 | for j in range(self.btpeer.btitpiroram.pointsnum): 73 | onepoint = self.btpeer.btitpiroram.usedcurve.G * realdatanumber[j] 74 | realpoints.append(onepoint) 75 | sumpoint = 0 76 | keys = list(forcircuitpoints.keys()) 77 | for k in forcircuitpoints: 78 | if k == keys[-1]: 79 | sumpoint = (realdatanumber[j] - sumpoint) % self.btpeer.btitpiroram.usedcurve.n 80 | forcircuitpoints[k].append(self.btpeer.btitpiroram.usedcurve.G * sumpoint) 81 | continue 82 | apoint = self.btpeer.btitpiroram.generaterandomnumber() 83 | sumpoint += apoint 84 | forcircuitpoints[k].append(self.btpeer.btitpiroram.usedcurve.G * apoint) 85 | 86 | #onepoint = baserandompoint 87 | #oneblock = oneblock + "|" + str(self.__generaterandomnumber()) 88 | #oneblock = oneblock + "|" + btitpiroram.convertfrompointtostring(onepoint) 89 | realpoints = [realpoints] 90 | realpointsstring = self.btpeer.btitpiroram.convertfrompointlisttostring(realpoints) #real data points 91 | forcircuitpointsstring = {} 92 | for i in forcircuitpoints: 93 | forcircuitpointsstring[i] = self.btpeer.btitpiroram.convertfrompointlisttostring([forcircuitpoints[i]]) #points strings for circuit peers 94 | 95 | for i in forcircuitpointsstring: 96 | host,port = i.split(':') 97 | singlecircuitdata = transactionid + "<<<" + forcircuitpointsstring[i] 98 | resp = self.btpeer.connectandsend(host, port, UPLOADCIRCUITSEND, singlecircuitdata) 99 | #upload finished 100 | del self.btpeer.uploadcircuitpeers[transactionid] 101 | 102 | 103 | def readdata_1( self, peerid, dataid ): 104 | host,port = peerid.split(':') 105 | msg = self.btpeer.myid + "<<<" + dataid 106 | resp = self.btpeer.connectandsend(host, port, READDATA1, msg) 107 | self.btdebug("readdata") 108 | #self.btdebug( resp) 109 | data = resp[0][1] 110 | transactionid, circuitpeersstr = data.split("<<<") 111 | #self.btpeer.fetchcircuitnum[transactionid] = len(circuitpeersstr.split(">>>")) 112 | 113 | 114 | 115 | def naiveinit(self, peerid): 116 | #response = self.btpeer.sendtopeer( peerid, NAIVEINIT, self.btpeer.myid ) 117 | self.btdebug( peerid) 118 | host,port = peerid.split(':') 119 | resp = self.btpeer.connectandsend( host, port, NAIVEINIT, self.btpeer.myid ) 120 | #print peerid + NAIVEINIT + self.btpeer.myid 121 | #print str(resp) 122 | if len(resp) > 0: 123 | data = resp[0][1] 124 | self.btpeer.bucketdata = str(data).split('>>>') 125 | number = self.btpeer.bucketdata[0] 126 | del self.btpeer.bucketdata[0] 127 | #print(number + " " + str(self.btpeer.bucketdata)) 128 | 129 | def uploaddata( self, peerid, dataid, datacontent ): 130 | host,port = peerid.split(':') 131 | senddata = dataid + ">>>" + datacontent 132 | resp = self.btpeer.connectandsend(host, port, UPLOADDATA, senddata) 133 | #data = resp[0][1] 134 | self.btdebug( resp) 135 | 136 | def readdata( self, peerid, dataid ): 137 | host,port = peerid.split(':') 138 | resp = self.btpeer.connectandsend(host, port, READDATA, dataid) 139 | self.btdebug("readdata") 140 | #data = resp[0][1] 141 | self.btdebug( resp) 142 | #return data 143 | 144 | def btdebug(self, msg): 145 | """ Prints a messsage to the screen with the name of the current thread """ 146 | print ("[%s] %s" % ( str(threading.currentThread().getName()), msg )) 147 | def debug (msg): 148 | #-------------------------------------------------------------------------- 149 | """ Print debug information. 150 | """ 151 | print(msg) 152 | 153 | def main(): 154 | if len(sys.argv) < 7: 155 | debug( "Syntax: %s -c 1 server-host server-port max-peers tracker-ip:port" % sys.argv[0]) 156 | sys.exit(-1) 157 | if sys.argv[3] != "0": 158 | serverhost = sys.argv[3] 159 | else: 160 | serverhost = None 161 | serverport = int(sys.argv[4]) 162 | print("serverport", serverport) 163 | maxpeers = sys.argv[5] 164 | peerid = sys.argv[6] 165 | app = BtClient( firstpeer=peerid, maxpeers=maxpeers, serverport=serverport, serverhost=serverhost ) 166 | #app.mainloop() 167 | #t = threading.Thread( target = app.mainloop(), args = [] ) 168 | #t.start() 169 | app.naiveinit_1(peerid) 170 | 171 | if __name__=='__main__': 172 | main() 173 | -------------------------------------------------------------------------------- /construction-1/btclient2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | Module implementing simple BerryTella GUI for a simple p2p network. 5 | """ 6 | 7 | 8 | import sys 9 | import threading 10 | import time 11 | 12 | #from Tkinter import * 13 | from random import * 14 | 15 | from btfiler import * 16 | 17 | 18 | 19 | class BtClient: 20 | def __init__( self, firstpeer, hops=2, maxpeers=5, serverport=5678, serverhost=None, master=None ): 21 | 22 | self.btpeer = FilerPeer( maxpeers, serverport, serverhost ) 23 | 24 | host,port = firstpeer.split(':') 25 | 26 | 27 | t = threading.Thread( target = self.btpeer.mainloop, args = [] ) 28 | t.start() 29 | #Cancel ping check 30 | self.btpeer.startstabilizer( self.btpeer.checklivepeers, 3 ) 31 | #self.btpeer.startstabilizer( self.onRefresh, 3 ) 32 | #self.after( 3000, self.onTimer ) 33 | #self.naiveinit(firstpeer) 34 | 35 | def naiveinit_1(self, peerid): 36 | #response = self.btpeer.sendtopeer( peerid, NAIVEINIT, self.btpeer.myid ) 37 | print("function naiveinit_1") 38 | self.btdebug(peerid) 39 | host,port = peerid.split(':') 40 | resp = self.btpeer.connectandsend( host, port, NAIVEINIT1, self.btpeer.myid ) 41 | #print peerid + NAIVEINIT + self.btpeer.myid 42 | #print str(resp) 43 | if len(resp) > 0: 44 | data = resp[0][1] 45 | self.btpeer.bucketdata = self.btpeer.btitpiroram.convertfromstringtopointlist(data) 46 | #number = self.btpeer.bucketdata[0] 47 | #del self.btpeer.bucketdata[0] 48 | #print("bucketdata", str(self.btpeer.bucketdata)) 49 | 50 | def uploaddata_1( self, peerid, dataid ): 51 | #upload time 52 | self.btpeer.uploadstarttime = time.time() 53 | host,port = peerid.split(':') 54 | senddata = dataid 55 | resp = self.btpeer.connectandsend(host, port, UPLOADDATA1, senddata) 56 | #data = resp[0][1] 57 | #self.btdebug( resp) 58 | data = resp[0][1] 59 | transactionid, uploadcircuitpeers = str(data).split('<<<') 60 | self.btpeer.uploadcircuitpeers[transactionid] = uploadcircuitpeers.split(">>>") 61 | 62 | #Generate a block, prepare points 63 | forcircuitpoints = {} 64 | for i in self.btpeer.uploadcircuitpeers[transactionid]: 65 | forcircuitpoints[i] = [] 66 | 67 | realpoints = [] 68 | realdatanumber = [] 69 | for i in range(self.btpeer.btitpiroram.pointsnum): 70 | realdatanumber.append(int(dataid.split("data")[1])) 71 | 72 | #realdatanumber = 1 #mock number for realdata 73 | #onepoint = btitpiroram.usedcurve.G * datapoint 74 | #oneblock = btitpiroram.convertfrompointtostring(onepoint) 75 | for j in range(self.btpeer.btitpiroram.pointsnum): 76 | onepoint = self.btpeer.btitpiroram.usedcurve.G * realdatanumber[j] 77 | realpoints.append(onepoint) 78 | sumpoint = 0 79 | keys = list(forcircuitpoints.keys()) 80 | for k in forcircuitpoints: 81 | if k == keys[-1]: 82 | sumpoint = (realdatanumber[j] - sumpoint) % self.btpeer.btitpiroram.usedcurve.n 83 | forcircuitpoints[k].append(self.btpeer.btitpiroram.usedcurve.G * sumpoint) 84 | continue 85 | apoint = self.btpeer.btitpiroram.generaterandomnumber() 86 | sumpoint += apoint 87 | forcircuitpoints[k].append(self.btpeer.btitpiroram.usedcurve.G * apoint) 88 | 89 | #onepoint = baserandompoint 90 | #oneblock = oneblock + "|" + str(self.__generaterandomnumber()) 91 | #oneblock = oneblock + "|" + btitpiroram.convertfrompointtostring(onepoint) 92 | realpoints = [realpoints] 93 | realpointsstring = self.btpeer.btitpiroram.convertfrompointlisttostring(realpoints) #real data points 94 | forcircuitpointsstring = {} 95 | for i in forcircuitpoints: 96 | forcircuitpointsstring[i] = self.btpeer.btitpiroram.convertfrompointlisttostring([forcircuitpoints[i]]) #points strings for circuit peers 97 | 98 | for i in forcircuitpointsstring: 99 | host,port = i.split(':') 100 | singlecircuitdata = transactionid + "<<<" + forcircuitpointsstring[i] 101 | resp = self.btpeer.connectandsend(host, port, UPLOADCIRCUITSEND, singlecircuitdata) 102 | #upload finished 103 | del self.btpeer.uploadcircuitpeers[transactionid] 104 | 105 | 106 | def readdata_1( self, peerid, dataid ): 107 | #fetch time 108 | self.btpeer.fetchstarttime = time.time() 109 | host,port = peerid.split(':') 110 | msg = self.btpeer.myid + "<<<" + dataid 111 | resp = self.btpeer.connectandsend(host, port, READDATA1, msg) 112 | self.btdebug("readdata") 113 | self.btdebug( resp) 114 | data = resp[0][1] 115 | transactionid, circuitpeersstr = data.split("<<<") 116 | #self.btpeer.fetchcircuitnum[transactionid] = len(circuitpeersstr.split(">>>")) 117 | #print("self.btpeer.fetchcircuitnum", self.btpeer.fetchcircuitnum) 118 | 119 | 120 | 121 | def naiveinit(self, peerid): 122 | #response = self.btpeer.sendtopeer( peerid, NAIVEINIT, self.btpeer.myid ) 123 | self.btdebug( peerid) 124 | host,port = peerid.split(':') 125 | resp = self.btpeer.connectandsend( host, port, NAIVEINIT, self.btpeer.myid ) 126 | #print peerid + NAIVEINIT + self.btpeer.myid 127 | #print str(resp) 128 | if len(resp) > 0: 129 | data = resp[0][1] 130 | self.btpeer.bucketdata = str(data).split('>>>') 131 | number = self.btpeer.bucketdata[0] 132 | del self.btpeer.bucketdata[0] 133 | print(number + " " + str(self.btpeer.bucketdata)) 134 | 135 | def uploaddata( self, peerid, dataid, datacontent ): 136 | host,port = peerid.split(':') 137 | senddata = dataid + ">>>" + datacontent 138 | resp = self.btpeer.connectandsend(host, port, UPLOADDATA, senddata) 139 | #data = resp[0][1] 140 | self.btdebug( resp) 141 | 142 | def readdata( self, peerid, dataid ): 143 | host,port = peerid.split(':') 144 | resp = self.btpeer.connectandsend(host, port, READDATA, dataid) 145 | self.btdebug("readdata") 146 | #data = resp[0][1] 147 | self.btdebug( resp) 148 | #return data 149 | 150 | def btdebug(self, msg): 151 | """ Prints a messsage to the screen with the name of the current thread """ 152 | print ("[%s] %s" % ( str(threading.currentThread().getName()), msg )) 153 | def debug (msg): 154 | #-------------------------------------------------------------------------- 155 | """ Print debug information. 156 | """ 157 | print(msg) 158 | 159 | def main(): 160 | if len(sys.argv) < 7: 161 | debug( "Syntax: %s -c 1 server-host server-port max-peers tracker-ip:port" % sys.argv[0]) 162 | sys.exit(-1) 163 | if sys.argv[3] != "0": 164 | serverhost = sys.argv[3] 165 | else: 166 | serverhost = None 167 | serverport = int(sys.argv[4]) 168 | maxpeers = sys.argv[5] 169 | peerid = sys.argv[6] 170 | app = BtClient( firstpeer=peerid, maxpeers=maxpeers, serverport=serverport, serverhost=serverhost ) 171 | #app.mainloop() 172 | #t = threading.Thread( target = app.mainloop(), args = [] ) 173 | #t.start() 174 | app.naiveinit_1(peerid) 175 | 176 | uploadN = 3 177 | 178 | for i in range(uploadN): 179 | app.uploaddata_1(peerid, "data"+str(i)) 180 | 181 | accessN = 9 182 | readsequence = [] 183 | for i in range(accessN): 184 | n = random.randint(0, uploadN-1) 185 | readsequence.append("data"+str(n)) 186 | 187 | count = 0 188 | for i in readsequence: 189 | count += 1 190 | print("fetch data", i, count) 191 | app.readdata_1(peerid, i) 192 | 193 | if __name__=='__main__': 194 | main() 195 | -------------------------------------------------------------------------------- /construction-1/btcrypto.py: -------------------------------------------------------------------------------- 1 | import base64 2 | import os 3 | from Crypto.Cipher import AES 4 | from Crypto import Random 5 | from Crypto.Random import random 6 | from random import shuffle 7 | 8 | class AESCipher: 9 | 10 | def __init__( self, key ): 11 | self.key = key 12 | self.BS = 16 13 | self.pad = lambda s: s + (self.BS - len(s) % self.BS) * chr(self.BS - len(s) % self.BS) 14 | self.unpad = lambda s : s[:-ord(s[len(s)-1:])] 15 | 16 | def encrypt( self, raw ): 17 | raw = self.pad(raw) 18 | #print AES.block_size 19 | iv = Random.new().read( AES.block_size ) 20 | cipher = AES.new( self.key, AES.MODE_CBC, iv ) 21 | return base64.b64encode( iv + cipher.encrypt( raw ) ) 22 | 23 | def decrypt( self, enc ): 24 | enc = base64.b64decode(enc) 25 | iv = enc[:16] 26 | cipher = AES.new(self.key, AES.MODE_CBC, iv ) 27 | return self.unpad(cipher.decrypt( enc[16:] )) 28 | 29 | def generateKey( size ): 30 | return Random.new().read(size) 31 | 32 | def generaterandomchoice( choicelist ): 33 | return random.choice(choicelist) 34 | 35 | -------------------------------------------------------------------------------- /construction-1/btserver0.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | Module implementing simple BerryTella GUI for a simple p2p network. 5 | """ 6 | 7 | 8 | import sys 9 | import threading 10 | 11 | #from Tkinter import * 12 | from random import * 13 | 14 | from btserverfiler import * 15 | 16 | 17 | class BTGui: 18 | def __init__( self, firstpeer, hops=2, maxpeers=5, serverport=5678, serverhost=None, master=None ): 19 | 20 | self.btpeer = FilerPeer( maxpeers, serverport, serverhost ) 21 | 22 | 23 | host,port = firstpeer.split(':') 24 | self.btpeer.buildpeers( host, int(port), hops=hops ) 25 | #self.updatePeerList() 26 | 27 | t = threading.Thread( target = self.btpeer.mainloop, args = [] ) 28 | t.start() 29 | 30 | self.btpeer.startstabilizer( self.btpeer.checklivepeers, 3 ) 31 | 32 | def debug (msg): 33 | #-------------------------------------------------------------------------- 34 | """ Print debug information. 35 | """ 36 | print(msg) 37 | 38 | 39 | 40 | 41 | def main(): 42 | if len(sys.argv) < 5: 43 | debug( "Syntax: %s server-host server-port max-peers peer-ip:port" % sys.argv[0]) 44 | sys.exit(-1) 45 | if sys.argv[1] != "0": 46 | serverhost = sys.argv[1] 47 | else: 48 | serverhost = None 49 | serverport = int(sys.argv[2]) 50 | maxpeers = sys.argv[3] 51 | peerid = sys.argv[4] 52 | app = BTGui( firstpeer=peerid, maxpeers=maxpeers, serverport=serverport, serverhost=serverhost ) 53 | #app.mainloop() 54 | 55 | 56 | # setup and run app 57 | if __name__=='__main__': 58 | main() 59 | -------------------------------------------------------------------------------- /construction-1/ecc/AffineCurvePoint.py: -------------------------------------------------------------------------------- 1 | # 2 | # joeecc - A small Elliptic Curve Cryptography Demonstration. 3 | # Copyright (C) 2011-2015 Johannes Bauer 4 | # 5 | # This file is part of joeecc. 6 | # 7 | # joeecc is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; this program is ONLY licensed under 10 | # version 3 of the License, later versions are explicitly excluded. 11 | # 12 | # joeecc is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with joeecc; if not, write to the Free Software 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | # 21 | # Johannes Bauer 22 | # 23 | 24 | import math 25 | 26 | from .FieldElement import FieldElement 27 | from .PointOps import PointOpEDDSAEncoding, PointOpCurveConversion, PointOpNaiveOrderCalculation 28 | 29 | class AffineCurvePoint(PointOpEDDSAEncoding, PointOpCurveConversion, PointOpNaiveOrderCalculation): 30 | """Represents a point on a curve in affine (x, y) representation.""" 31 | 32 | def __init__(self, x, y, curve): 33 | """Generate a curve point (x, y) on the curve 'curve'. x and y have to 34 | be integers. If the neutral element of the group O (for some curves, 35 | this is a point at infinity) should be created, use the static method 36 | 'neutral', since representations of O differ on various curves (e.g. in 37 | short Weierstrass curves, they have no explicit notation in affine 38 | space while on twisted Edwards curves they do.""" 39 | # Either x and y are None (Point at Infty) or both are defined 40 | assert(((x is None) and (y is None)) or ((x is not None) and (y is not None))) 41 | assert((x is None) or isinstance(x, int)) 42 | assert((y is None) or isinstance(y, int)) 43 | if x is None: 44 | # Point at infinity 45 | self._x = None 46 | self._y = None 47 | else: 48 | self._x = FieldElement(x, curve.p) 49 | self._y = FieldElement(y, curve.p) 50 | self._curve = curve 51 | 52 | @staticmethod 53 | def neutral(curve): 54 | """Returns the neutral element of the curve group.""" 55 | return curve.neutral() 56 | 57 | @property 58 | def is_neutral(self): 59 | """Indicates if the point is the neutral element O of the curve (point 60 | at infinity for some curves).""" 61 | return self.curve.is_neutral(self) 62 | 63 | @property 64 | def x(self): 65 | """Affine X component of the point, field element of p.""" 66 | return self._x 67 | 68 | @property 69 | def y(self): 70 | """Affine Y component of the point, field element of p.""" 71 | return self._y 72 | 73 | @property 74 | def curve(self): 75 | """Curve that the point is located on.""" 76 | return self._curve 77 | 78 | def __add__(self, other): 79 | """Returns the point addition.""" 80 | assert(isinstance(other, AffineCurvePoint)) 81 | return self.curve.point_addition(self, other) 82 | 83 | def __rmul__(self, other): 84 | return self * other 85 | 86 | def __neg__(self): 87 | """Returns the point negation.""" 88 | return self.curve.point_conjugate(self) 89 | 90 | def __mul__(self, scalar): 91 | """Returns the scalar point multiplication. The scalar needs to be an 92 | integer value.""" 93 | assert(isinstance(scalar, int)) 94 | assert(scalar >= 0) 95 | 96 | result = self.curve.neutral() 97 | n = self 98 | if scalar > 0: 99 | for bit in range(scalar.bit_length()): 100 | if (scalar & (1 << bit)): 101 | result = result + n 102 | n = n + n 103 | assert(result.oncurve()) 104 | return result 105 | 106 | def __eq__(self, other): 107 | return (self.x, self.y) == (other.x, other.y) 108 | 109 | def __ne__(self, other): 110 | return not (self == other) 111 | 112 | def oncurve(self): 113 | """Indicates if the given point is satisfying the curve equation (i.e. 114 | if it is a point on the curve).""" 115 | return self.curve.oncurve(self) 116 | 117 | def compress(self): 118 | """Returns the compressed point format (if this is possible on the 119 | given curve).""" 120 | return self.curve.compress(self) 121 | 122 | def __repr__(self): 123 | return str(self) 124 | 125 | def __str__(self): 126 | if self.is_neutral: 127 | return "(neutral)" 128 | else: 129 | return "(0x%x, 0x%x)" % (int(self.x), int(self.y)) 130 | 131 | 132 | -------------------------------------------------------------------------------- /construction-1/ecc/ECPrivateKey.py: -------------------------------------------------------------------------------- 1 | from .PrivKeyOps import PrivKeyOpECDSASign, PrivKeyOpECIESDecrypt, PrivKeyOpEDDSASign, PrivKeyOpEDDSAKeyGen, PrivKeyOpEDDSAEncode, PrivKeyOpECDH 2 | from .ECPublicKey import ECPublicKey 3 | from .Random import secure_rand_int_between 4 | 5 | class ECPrivateKey(PrivKeyOpECDSASign, PrivKeyOpECIESDecrypt, PrivKeyOpEDDSASign, PrivKeyOpEDDSAKeyGen, PrivKeyOpEDDSAEncode, PrivKeyOpECDH): 6 | """Represents an elliptic curve private key.""" 7 | 8 | def __init__(self, scalar, curve): 9 | """Initialize the private key with the given scalar on the given 10 | curve.""" 11 | self._seed = None 12 | self._scalar = scalar 13 | self._curve = curve 14 | self._pubkey = ECPublicKey(self._scalar * self._curve.G) 15 | 16 | @property 17 | def scalar(self): 18 | """Returns the private scalar d of the key.""" 19 | return self._scalar 20 | 21 | @property 22 | def curve(self): 23 | """Returns the group which is used for EC computations.""" 24 | return self._curve 25 | 26 | @property 27 | def pubkey(self): 28 | """Returns the public key that is the counterpart to this private key.""" 29 | return self._pubkey 30 | 31 | @property 32 | def seed(self): 33 | """Returns the seed or None if there wasn't one. A seed is used for 34 | schemes like EdDSA; it basically is a binary string that is hashed to 35 | yield that actual private scalar d.""" 36 | return self._seed 37 | 38 | def set_seed(self, seed): 39 | """Sets the seed of the private key. This operation can only performed 40 | if no scalar has previously been set for this key.""" 41 | assert(self._seed is None) 42 | self._seed = seed 43 | return self 44 | 45 | @staticmethod 46 | def generate(curve): 47 | """Generate a random private key on a given curve.""" 48 | scalar = secure_rand_int_between(1, curve.n - 1) 49 | return ECPrivateKey(scalar, curve) 50 | 51 | def __str__(self): 52 | if self._seed is None: 53 | return "PrivateKey" % (self.scalar) 54 | else: 55 | seedstr = "".join("%02x" % (c) for c in self._seed) 56 | return "PrivateKey" % (self.scalar, seedstr) 57 | 58 | -------------------------------------------------------------------------------- /construction-1/ecc/ECPublicKey.py: -------------------------------------------------------------------------------- 1 | from .PubKeyOps import PubKeyOpECDSAVerify, PubKeyOpECDSAExploitReusedNonce, PubKeyOpEDDSAVerify, PubKeyOpEDDSAEncode, PubKeyOpECIESEncrypt 2 | 3 | class ECPublicKey(PubKeyOpECDSAVerify, PubKeyOpECDSAExploitReusedNonce, PubKeyOpEDDSAVerify, PubKeyOpEDDSAEncode, PubKeyOpECIESEncrypt): 4 | """Elliptic curve public key abstraction. An EC public key is just a point 5 | on the curve, which is why the constructor only takes this (public) point 6 | as a parameter. The public key abstraction allows this point to be used in 7 | various meaningful purposes (ECDSA signature verification, etc.).""" 8 | 9 | def __init__(self, point): 10 | self._point = point 11 | 12 | @property 13 | def curve(self): 14 | return self._point.curve 15 | 16 | @property 17 | def point(self): 18 | return self._point 19 | 20 | def __str__(self): 21 | return "PublicKey<%s>" % (str(self.point)) 22 | -------------------------------------------------------------------------------- /construction-1/ecc/EllipticCurve.py: -------------------------------------------------------------------------------- 1 | from .AffineCurvePoint import AffineCurvePoint 2 | 3 | class EllipticCurve(object): 4 | """Elliptic curve base class. Provides functionality which all curves have 5 | in common.""" 6 | 7 | @property 8 | def curve_order(self): 9 | """Returns the order of the curve, i.e. #E(F_p). Intuitively, this is 10 | the total number of points on the curve (plus maybe points at ininity, 11 | depending on the curve type) that satisfy the curve equation.""" 12 | return self.h * self.n 13 | 14 | @property 15 | def domainparams(self): 16 | """Returns the curve parameters as a named tuple.""" 17 | raise Exception(NotImplemented) 18 | 19 | @property 20 | def hasgenerator(self): 21 | """Returns if a generator point was supplied for the curve.""" 22 | return self.G is not None 23 | 24 | @property 25 | def hasname(self): 26 | """Returns if the curve is named (i.e. its name is not None).""" 27 | return self.name is not None 28 | 29 | @property 30 | def name(self): 31 | """Returns the name of the curve, if it was given one during 32 | construction. Purely informational.""" 33 | return self._name 34 | 35 | @property 36 | def curvetype(self): 37 | """Returns a string that corresponds to the curve type. For example, 38 | this string can be 'shortweierstrass', 'twistededwards' or 39 | 'montgomery'.""" 40 | raise Exception(NotImplemented) 41 | 42 | def enumerate_points(self): 43 | """Enumerates all points on the curve, including the point at infinity 44 | (if the curve has such a special point).""" 45 | raise Exception(NotImplemented) 46 | 47 | def naive_order_calculation(self): 48 | """Naively calculates the order #E(F_p) of the curve by enumerating and 49 | counting all points which fulfull the curve equation. Note that this 50 | implementation only works for the smallest of curves and is 51 | computationally infeasible for all practical applications.""" 52 | order = 0 53 | for pt in self.enumerate_points(): 54 | order += 1 55 | return order 56 | 57 | def neutral(self): 58 | """Returns the neutral element of the curve group (for some curves, 59 | this will be the point at infinity).""" 60 | return AffineCurvePoint(None, None, self) 61 | 62 | def is_neutral(self, P): 63 | """Checks if a given point P is the neutral element of the group.""" 64 | return P.x is None 65 | 66 | def oncurve(self, P): 67 | """Checks is a given point P is on the curve.""" 68 | raise Exception(NotImplemented) 69 | 70 | def point_addition(self, P, Q): 71 | """Returns the sum of two points P and Q on the curve.""" 72 | raise Exception(NotImplemented) 73 | 74 | def compress(self, P): 75 | """Returns the compressed representation of the point P on the 76 | curve. Not all curves may support this operation.""" 77 | raise Exception(NotImplemented) 78 | 79 | def uncompress(self, compressed): 80 | """Returns the uncompressed representation of a point on the curve. Not 81 | all curves may support this operation.""" 82 | raise Exception(NotImplemented) 83 | 84 | def __eq__(self, other): 85 | return self.domainparams == other.domainparams 86 | 87 | def __ne__(self, other): 88 | return not (self == other) 89 | 90 | -------------------------------------------------------------------------------- /construction-1/ecc/FieldElement.py: -------------------------------------------------------------------------------- 1 | # 2 | # joeecc - A small Elliptic Curve Cryptography Demonstration. 3 | # Copyright (C) 2011-2015 Johannes Bauer 4 | # 5 | # This file is part of joeecc. 6 | # 7 | # joeecc is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; this program is ONLY licensed under 10 | # version 3 of the License, later versions are explicitly excluded. 11 | # 12 | # joeecc is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with joeecc; if not, write to the Free Software 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | # 21 | # Johannes Bauer 22 | # 23 | 24 | import random 25 | 26 | class FieldElement(object): 27 | """Represents an element in a finite field over a (prime) modulus.""" 28 | 29 | def __init__(self, intvalue, modulus): 30 | assert(isinstance(intvalue, int)) 31 | assert(isinstance(modulus, int)) 32 | self._intvalue = intvalue % modulus 33 | self._modulus = modulus 34 | self._qnr = None 35 | 36 | @property 37 | def modulus(self): 38 | """Returns the field's modulus.""" 39 | return self._modulus 40 | 41 | @staticmethod 42 | def _eea(a, b): 43 | """Extended euclidian algorithm. Returns the gcd of (a, b) and the 44 | Bezout-coefficients.""" 45 | assert(isinstance(a, int)) 46 | assert(isinstance(b, int)) 47 | (s, t, u, v) = (1, 0, 0, 1) 48 | while b != 0: 49 | (q, r) = (a // b, a % b) 50 | (unew, vnew) = (s, t) 51 | s = u - (q * s) 52 | t = v - (q * t) 53 | (a, b) = (b, r) 54 | (u, v) = (unew, vnew) 55 | return (a, u, v) 56 | 57 | def inverse(self): 58 | if int(self) == 0: 59 | raise Exception("Trying to invert zero") 60 | (gcd, u, v) = self._eea(int(self), self.modulus) 61 | return FieldElement(v, self.modulus) 62 | 63 | @property 64 | def is_qr(self): 65 | """Returns if the number is a quadratic residue according to Euler's 66 | criterion.""" 67 | return not self.is_qnr 68 | 69 | @property 70 | def is_qnr(self): 71 | """Returns if the number is a quadratic non-residue according to 72 | Euler's criterion.""" 73 | if self._qnr is None: 74 | self._qnr = int(self ** ((self._modulus - 1) // 2)) != 1 75 | return self._qnr 76 | 77 | def _tonelli_shanks_sqrt(self): 78 | """Performs the Tonelli-Shanks algorithm to determine the square root 79 | on an element. Note that the algorithm only works if the value it is 80 | performed on is a quadratic residue mod p.""" 81 | q = self._modulus - 1 82 | s = 0 83 | while (q % 2) == 0: 84 | s += 1 85 | q >>= 1 86 | assert(q * (2 ** s) == self.modulus - 1) 87 | 88 | while True: 89 | z = FieldElement(random.randint(1, self.modulus - 1), self.modulus) 90 | if z.is_qnr: 91 | break 92 | assert(z.is_qnr) 93 | c = z ** q 94 | 95 | r = self ** ((q + 1) // 2) 96 | t = self ** q 97 | m = s 98 | while int(t) != 1: 99 | for i in range(1, m): 100 | if int(t ** (1 << i)) == 1: 101 | break 102 | 103 | b = c ** (1 << (m - i - 1)) 104 | r = r * b 105 | t = t * (b ** 2) 106 | c = b ** 2 107 | m = i 108 | 109 | return r 110 | 111 | def sqr(self): 112 | """Return the squared value.""" 113 | return self * self 114 | 115 | def sqrt(self): 116 | """Returns the square root of the value or None if the value is a 117 | quadratic non-residue mod p.""" 118 | if self.is_qnr: 119 | return None 120 | 121 | if (self._modulus % 4) == 3: 122 | root = self ** ((self._modulus + 1) // 4) 123 | assert(root * root == self) 124 | else: 125 | root = self._tonelli_shanks_sqrt() 126 | 127 | if (int(root) & 1) == 0: 128 | return (root, -root) 129 | else: 130 | return (-root, root) 131 | 132 | def __checktype(self, value): 133 | if isinstance(value, int): 134 | return value 135 | elif isinstance(value, FieldElement): 136 | if value.modulus == self.modulus: 137 | return int(value) 138 | else: 139 | raise Exception("Cannot perform meaningful arithmetic operations on field elements in different fields.") 140 | else: 141 | raise TypeError("Unsupported type for operations with field element: (%s) %s" % (str(type(value)), str(value))) 142 | 143 | def sigint(self): 144 | """Returns a signed integer if the negative value is less than 10 145 | decimal digits and the absolute negated value is smaller than the 146 | absolute positive value.""" 147 | neg = abs(int(-self)) 148 | if (neg < int(self)) and (neg < 1000000000): 149 | return -neg 150 | else: 151 | return int(self) 152 | 153 | def __int__(self): 154 | return self._intvalue 155 | 156 | def __add__(self, value): 157 | value = self.__checktype(value) 158 | return FieldElement(int(self) + value, self.modulus) 159 | 160 | def __sub__(self, value): 161 | value = self.__checktype(value) 162 | return FieldElement(int(self) - value, self.modulus) 163 | 164 | def __mul__(self, value): 165 | value = self.__checktype(value) 166 | return FieldElement(int(self) * value, self.modulus) 167 | 168 | def __floordiv__(self, value): 169 | value = self.__checktype(value) 170 | return self * FieldElement(value, self.modulus).inverse() 171 | 172 | def __pow__(self, exponent): 173 | assert(isinstance(exponent, int)) 174 | return FieldElement(pow(int(self), exponent, self.modulus), self.modulus) 175 | 176 | def __neg__(self): 177 | return FieldElement(-int(self), self.modulus) 178 | 179 | def __radd__(self, value): 180 | return self + value 181 | 182 | def __rsub__(self, value): 183 | return -self + value 184 | 185 | def __rmul__(self, value): 186 | return self * value 187 | 188 | def __rfloordiv__(self, value): 189 | return self.inverse() * value 190 | 191 | def __eq__(self, value): 192 | value = self.__checktype(value) 193 | return int(self) == value 194 | 195 | def __ne__(self, other): 196 | return not (self == other) 197 | 198 | def __lt__(self, other): 199 | return int(self) < int(other) 200 | 201 | def __repr__(self): 202 | return str(self) 203 | 204 | def __str__(self): 205 | return "{0x%x}" % (int(self)) 206 | 207 | -------------------------------------------------------------------------------- /construction-1/ecc/MontgomeryCurve.py: -------------------------------------------------------------------------------- 1 | # 2 | # joeecc - A small Elliptic Curve Cryptography Demonstration. 3 | # Copyright (C) 2011-2015 Johannes Bauer 4 | # 5 | # This file is part of joeecc. 6 | # 7 | # joeecc is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; this program is ONLY licensed under 10 | # version 3 of the License, later versions are explicitly excluded. 11 | # 12 | # joeecc is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with joeecc; if not, write to the Free Software 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | # 21 | # Johannes Bauer 22 | # 23 | 24 | import collections 25 | from .FieldElement import FieldElement 26 | from .AffineCurvePoint import AffineCurvePoint 27 | from .EllipticCurve import EllipticCurve 28 | import ecc.TwistedEdwardsCurve 29 | 30 | _MontgomeryCurveDomainParameters = collections.namedtuple("MontgomeryCurveDomainParameters", [ "curvetype", "a", "b", "p", "n", "G" ]) 31 | 32 | class MontgomeryCurve(EllipticCurve): 33 | """Represents an elliptic curve over a finite field F_P that satisfies the 34 | Montgomery equation by^2 = x^3 + ax^2 + x.""" 35 | 36 | def __init__(self, a, b, p, n, h, Gx, Gy, **kwargs): 37 | """Create an elliptic Montgomery curve given the equation coefficients 38 | a and b, the curve modulus p, the order of the curve n, the cofactor of 39 | the curve h and the generator point G's X and Y coordinates in affine 40 | representation, Gx and Gy.""" 41 | 42 | EllipticCurve.__init__(self) 43 | assert(isinstance(a, int)) # Curve coefficent A 44 | assert(isinstance(b, int)) # Curve coefficent B 45 | assert(isinstance(p, int)) # Modulus 46 | assert(isinstance(n, int)) # Order 47 | assert(isinstance(h, int)) # Cofactor 48 | assert((Gx is None) or isinstance(Gx, int)) # Generator Point X 49 | assert((Gy is None) or isinstance(Gy, int)) # Generator Point Y 50 | self._a = FieldElement(a, p) 51 | self._b = FieldElement(b, p) 52 | self._p = p 53 | self._n = n 54 | self._h = h 55 | self._name = kwargs.get("name") 56 | 57 | # Check that the curve is not singular 58 | assert(self.b * ((self.a ** 2) - 4) != 0) 59 | 60 | if (Gx is not None) or (Gy is not None): 61 | # Check that the generator G is on the curve 62 | self._G = AffineCurvePoint(Gx, Gy, self) 63 | assert(self._G.oncurve()) 64 | 65 | # Check that the generator G is of curve order 66 | assert((self.n * self.G).is_neutral) 67 | else: 68 | self._G = None 69 | 70 | @property 71 | def domainparams(self): 72 | return _MontgomeryCurveDomainParameters(curvetype = self.curvetype, a = self.a, b = self.b, p = self.p, n = self.n, G = self.G) 73 | 74 | @property 75 | def curvetype(self): 76 | return "montgomery" 77 | 78 | @property 79 | def a(self): 80 | return self._a 81 | 82 | @property 83 | def b(self): 84 | return self._b 85 | 86 | @property 87 | def p(self): 88 | return self._p 89 | 90 | @property 91 | def n(self): 92 | return self._n 93 | 94 | @property 95 | def h(self): 96 | return self._h 97 | 98 | @property 99 | def G(self): 100 | return self._G 101 | 102 | def oncurve(self, P): 103 | return (P.is_neutral) or ((self.b * P.y ** 2) == (P.x ** 3) + (self.a * (P.x ** 2)) + P.x) 104 | 105 | def point_conjugate(self, P): 106 | return AffineCurvePoint(int(P.x), int(-P.y), self) 107 | 108 | def point_addition(self, P, Q): 109 | if P.is_neutral: 110 | # P is at infinity, O + Q = Q 111 | result = Q 112 | elif P == -Q: 113 | # P == -Q, return O (point at infinity) 114 | result = AffineCurvePoint.neutral(self) 115 | elif P == Q: 116 | # P == Q, point doubling 117 | newx = -2 * P.x - self.a + (3 * P.x**2 + 2 * P.x * self.a + 1)**2 // (4 * P.y**2 * self.b) 118 | newy = -P.y + (3 * P.x**2 + 2 * P.x * self.a + 1) * (3 * P.x + self.a) // (2 * P.y * self.b) - (3 * P.x**2 + 2 * P.x * self.a + 1)**3 // (8 * P.y**3 * self.b**2) 119 | result = AffineCurvePoint(int(newx), int(newy), self) 120 | else: 121 | # P != Q, point addition 122 | newx = -P.x - Q.x - self.a + (P.y - Q.y)**2 * self.b // (P.x - Q.x)**2 123 | newy = (2 * P.x + Q.x + self.a) * (P.y - Q.y) // (P.x - Q.x) - P.y - (P.y - Q.y)**3 * self.b // (P.x - Q.x)**3 124 | result = AffineCurvePoint(int(newx), int(newy), self) 125 | return result 126 | 127 | def to_twistededwards(self, a = None): 128 | """Converts the domain parameters of this curve to domain parameters of 129 | a birationally equivalent twisted Edwards curve. The user may select a 130 | desired a coefficient that the resulting Edwards curve shall have or 131 | leave it at None to accept an arbitrary one.""" 132 | assert((a is None) or isinstance(a, int)) 133 | 134 | # For the Montgomery curve, B can always be arbitrarily chosen as long 135 | # as the surrogate B coeffients are identical in their quadratic 136 | # residue property mod p. This means an Montgomery curve where B is a 137 | # quadratic residue mod p is isomorphous to all other Montgomery curves 138 | # with identical A, p and where B is also a quadratic residue mod p. We 139 | # use this property to get the curve we want if there is a desired "a" 140 | # outcome and choose B appropriately. 141 | if a is None: 142 | # No special wish for a, just do the normal conversion 143 | conversion_b = self.b 144 | a = (self.a + 2) // conversion_b 145 | else: 146 | # We desire a special a and calculate the B we want 147 | conversion_b = (self.a + 2) // a 148 | 149 | # And assure that it's QR property is the same as the original 150 | assert(conversion_b.is_qr == self.b.is_qr) 151 | d = (self.a - 2) // conversion_b 152 | 153 | # Then construct a curve with no generator first 154 | raw_curve = ecc.TwistedEdwardsCurve.TwistedEdwardsCurve( 155 | a = int(a), 156 | d = int(d), 157 | p = self.p, 158 | n = self.n, 159 | h = self.h, 160 | Gx = None, 161 | Gy = None, 162 | ) 163 | 164 | # Convert the generator point to the new curve 165 | G_twed = self.G.convert(raw_curve) 166 | 167 | # And recreate the curve with this new generator 168 | twed_curve = ecc.TwistedEdwardsCurve.TwistedEdwardsCurve( 169 | a = int(a), 170 | d = int(d), 171 | p = self.p, 172 | n = self.n, 173 | h = self.h, 174 | Gx = int(G_twed.x), 175 | Gy = int(G_twed.y), 176 | ) 177 | return twed_curve 178 | 179 | 180 | def __str__(self): 181 | if self.hasname: 182 | return "MontgomeryCurve<%s>" % (self.name) 183 | else: 184 | return "MontgomeryCurve<0x%x y^2 = x^3 + 0x%x x^2 + x mod 0x%x>" % (int(self.b), int(self.a), int(self.p)) 185 | -------------------------------------------------------------------------------- /construction-1/ecc/PointOps.py: -------------------------------------------------------------------------------- 1 | from . import Tools 2 | from .FieldElement import FieldElement 3 | 4 | class PointOpEDDSAEncoding(object): 5 | def eddsa_encode(self): 6 | """Performs serialization of the point as required by EdDSA.""" 7 | bitlen = self.curve.p.bit_length() 8 | enc_value = int(self.y) 9 | enc_value &= ((1 << bitlen) - 1) 10 | enc_value |= (int(self.x) & 1) << bitlen 11 | return Tools.inttobytes_le(enc_value, self.curve.B // 8) 12 | 13 | @staticmethod 14 | def __eddsa_recoverx(curve, y): 15 | xx = (y * y - 1) // (curve.d * y * y + 1) 16 | x = xx ** ((curve.p + 3) // 8) 17 | if x * x != xx: 18 | I = FieldElement(-1, curve.p).sqrt()[0] 19 | x = x * I 20 | if (int(x) % 2) != 0: 21 | x = -x 22 | return int(x) 23 | 24 | @classmethod 25 | def eddsa_decode(cls, curve, data): 26 | """Performs deserialization of the point as required by EdDSA.""" 27 | assert(curve.curvetype == "twistededwards") 28 | bitlen = curve.p.bit_length() 29 | enc_value = Tools.bytestoint_le(data) 30 | y = enc_value & ((1 << bitlen) - 1) 31 | x = PointOpEDDSAEncoding.__eddsa_recoverx(curve, y) 32 | hibit = (enc_value >> bitlen) & 1 33 | if (x & 1) != hibit: 34 | x = curve.p - x 35 | return cls(x, y, curve) 36 | 37 | class PointOpCurveConversion(object): 38 | @staticmethod 39 | def __pconv_twed_mont_scalefactor(twedcurve, montcurve): 40 | native_b = 4 // (twedcurve.a - twedcurve.d) 41 | if native_b == montcurve.b: 42 | # Scaling is not necessary, already native curve format 43 | scale_factor = 1 44 | else: 45 | # Scaling of montgomery y component (v) is needed 46 | if twedcurve.hasgenerator and montcurve.hasgenerator: 47 | # Convert the generator point of the twisted edwards source 48 | # point to unscaled Montgomery space 49 | Gv = (1 + twedcurve.G.y) // ((1 - twedcurve.G.y) * twedcurve.G.x) 50 | 51 | # And calculate a multiplicative scaling factor so that the 52 | # point will result in the target curve's generator point Y 53 | scale_factor = montcurve.G.y // Gv 54 | 55 | elif native_b.is_qr: 56 | # If b is a quadradic residue mod p then any other 57 | # quadratic residue can serve as a surrgate b coefficient 58 | # to yield an isomorphous curve. Only y coordinate of the 59 | # resulting points needs to be scaled. Calculate a scaling 60 | # ratio. 61 | scale_factors = (montcurve.b // native_b).sqrt() 62 | 63 | # At least one of the curves lacks a generator point, 64 | # select just any scale factor 65 | scale_factor = scale_factors[0].inverse() 66 | 67 | else: 68 | # Native B is a quadratic non-residue module B; Not sure 69 | # how to handle this case 70 | # TODO: Implement this 71 | raise Exception(NotImplemented) 72 | return scale_factor 73 | 74 | def convert(self, targetcurve): 75 | """Convert the affine curve point to a point on a birationally 76 | equivalent target curve.""" 77 | 78 | if self.is_neutral: 79 | return targetcurve.neutral() 80 | 81 | if (self.curve.curvetype == "twistededwards") and (targetcurve.curvetype == "montgomery"): 82 | # (x, y) are Edwards coordinates 83 | # (u, v) are Montgomery coordonates 84 | (x, y) = (self.x, self.y) 85 | u = (1 + y) // (1 - y) 86 | v = (1 + y) // ((1 - y) * x) 87 | 88 | # Montgomery coordinates are unscaled to the actual B coefficient 89 | # of the curve right now. Calculate scaling factor and scale v 90 | # appropriately 91 | scaling_factor = self.__pconv_twed_mont_scalefactor(self.curve, targetcurve) 92 | v = v * scaling_factor 93 | 94 | point = self.__class__(int(u), int(v), targetcurve) 95 | elif (self.curve.curvetype == "montgomery") and (targetcurve.curvetype == "twistededwards"): 96 | # (x, y) are Edwards coordinates 97 | # (u, v) are Montgomery coordonates 98 | (u, v) = (self.x, self.y) 99 | y = (u - 1) // (u + 1) 100 | x = -(1 + y) // (v * (y - 1)) 101 | 102 | # Twisted Edwards coordinates are unscaled to the actual B 103 | # coefficient of the curve right now. Calculate scaling factor and 104 | # scale x appropriately 105 | scaling_factor = self.__pconv_twed_mont_scalefactor(targetcurve, self.curve) 106 | x = x * scaling_factor 107 | 108 | point = self.__class__(int(x), int(y), targetcurve) 109 | else: 110 | raise Exception(NotImplemented) 111 | 112 | assert(point.oncurve()) 113 | return point 114 | 115 | class PointOpNaiveOrderCalculation(object): 116 | def naive_order_calculation(self): 117 | """Calculates the order of the point naively, i.e. by walking through 118 | all points until the given neutral element is hit. Note that this only 119 | works for smallest of curves and is not computationally feasible for 120 | anything else.""" 121 | curpt = self 122 | order = 1 123 | while not curpt.is_neutral: 124 | order += 1 125 | curpt += self 126 | return order 127 | 128 | -------------------------------------------------------------------------------- /construction-1/ecc/PrivKeyOps.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | import collections 3 | 4 | from .FieldElement import FieldElement 5 | from .Random import secure_rand, secure_rand_int_between 6 | from .AffineCurvePoint import AffineCurvePoint 7 | from . import Tools 8 | 9 | class PrivKeyOpECDSASign(object): 10 | ECDSASignature = collections.namedtuple("ECDSASignature", [ "hashalg", "r", "s" ]) 11 | 12 | def ecdsa_sign_hash(self, message_digest, k = None, digestname = None): 13 | """Signs a given messagedigest, given as bytes, using ECDSA. 14 | Optionally a nonce k can be supplied which should usually be unqiuely 15 | chosen for every ECDSA signature. This way it is possible to 16 | deliberately create broken signatures which can be exploited later on. 17 | If k is not supplied, it is randomly chosen. If a digestname is 18 | supplied the name of this digest eventually ends up in the 19 | ECDSASignature object.""" 20 | assert(isinstance(message_digest, bytes)) 21 | assert((k is None) or isinstance(k, int)) 22 | 23 | # Convert message digest to integer value 24 | e = Tools.ecdsa_msgdigest_to_int(message_digest, self.curve.n) 25 | 26 | # Select a random integer (if None is supplied!) 27 | if k is None: 28 | k = secure_rand_int_between(1, self.curve.n - 1) 29 | 30 | # r = (k * G)_x mod n 31 | Rmodp = k * self.curve.G 32 | r = int(Rmodp.x) % self.curve.n 33 | assert(r != 0) 34 | 35 | s = FieldElement(e + self.scalar * r, self.curve.n) // k 36 | 37 | return self.ECDSASignature(r = r, s = int(s), hashalg = digestname) 38 | 39 | def ecdsa_sign(self, message, digestname, k = None): 40 | """Signs a given message with the digest that is given as a string. 41 | Optionally a nonce k can be supplied which should usually be unqiuely 42 | chosen for every ECDSA signature. This way it is possible to 43 | deliberately create broken signatures which can be exploited later 44 | on. If k is not supplied, it is randomly chosen.""" 45 | assert(isinstance(message, bytes)) 46 | assert(isinstance(digestname, str)) 47 | digest_fnc = hashlib.new(digestname) 48 | digest_fnc.update(message) 49 | message_digest = digest_fnc.digest() 50 | return self.ecdsa_sign_hash(message_digest, k = k, digestname = digestname) 51 | 52 | 53 | class PrivKeyOpECIESDecrypt(object): 54 | def ecies_decrypt(self, R): 55 | """Takes the transmitted point R and reconstructs the shared secret 56 | point S using the private key.""" 57 | # Transmitted R is given, restore the symmetric key S 58 | return self._scalar * R 59 | 60 | 61 | class PrivKeyOpEDDSASign(object): 62 | class EDDSASignature(object): 63 | def __init__(self, curve, R, s): 64 | self._curve = curve 65 | self._R = R 66 | self._s = s 67 | 68 | @property 69 | def curve(self): 70 | return self._curve 71 | 72 | @property 73 | def R(self): 74 | return self._R 75 | 76 | @property 77 | def s(self): 78 | return self._s 79 | 80 | def encode(self): 81 | """Performs serialization of the signature as used by EdDSA.""" 82 | return self.R.eddsa_encode() + Tools.inttobytes_le(self.s, self.curve.B // 8) 83 | 84 | @classmethod 85 | def decode(cls, curve, encoded_signature): 86 | """Performs deserialization of the signature as used by EdDSA.""" 87 | assert(isinstance(encoded_signature, bytes)) 88 | assert(len(encoded_signature) == 64) 89 | encoded_R = encoded_signature[:32] 90 | encoded_s = encoded_signature[32:] 91 | R = AffineCurvePoint.eddsa_decode(curve, encoded_R) 92 | s = Tools.bytestoint_le(encoded_s) 93 | return cls(curve, R, s) 94 | 95 | def __eq__(self, other): 96 | return (self.R, self.s) == (other.R, other.s) 97 | 98 | def __str__(self): 99 | return "EDDSASignature" % (self.R, self.s) 100 | 101 | @staticmethod 102 | def __eddsa_hash(data): 103 | return hashlib.sha512(data).digest() 104 | 105 | @staticmethod 106 | def __eddsa_bitof(data, bitno): 107 | return (data[bitno // 8] >> (bitno % 8)) & 1 108 | 109 | def eddsa_sign(self, message): 110 | """Performs an EdDSA signature of the message. For this to work the 111 | curve has to be a twisted Edwards curve and the private key scalar has 112 | to be generated from a hashed seed. This hashed seed is automatically 113 | generated when a keypair is generated using, for example, the 114 | eddsa_generate() function instead of the regular key generation 115 | function generate().""" 116 | assert(self.curve.curvetype == "twistededwards") 117 | if self._seed is None: 118 | raise Exception("EDDSA requires a seed which is the source for calculation of the private key scalar.") 119 | h = self.__eddsa_hash(self._seed) 120 | r = Tools.bytestoint_le(self.__eddsa_hash(h[32 : 64] + message)) 121 | R = r * self.curve.G 122 | s = (r + Tools.bytestoint_le(self.__eddsa_hash(R.eddsa_encode() + self.pubkey.point.eddsa_encode() + message)) * self.scalar) % self.curve.n 123 | sig = self.EDDSASignature(self.curve, R, s) 124 | return sig 125 | 126 | 127 | class PrivKeyOpEDDSAKeyGen(object): 128 | @staticmethod 129 | def __eddsa_bitof(data, bitpos): 130 | return (data[bitpos // 8] >> (bitpos % 8)) & 1 131 | 132 | @staticmethod 133 | def __eddsa_bitstring(data, bitcnt): 134 | return sum((PrivKeyOpEDDSAKeyGen.__eddsa_bitof(data, bitpos)) << bitpos for bitpos in range(bitcnt)) 135 | 136 | @classmethod 137 | def eddsa_generate(cls, curve, seed = None): 138 | """Generates a randomly selected seed value. This seed value is then 139 | hashed using the EdDSA hash function (usually SHA512) and the resulting 140 | value is (slightly modified) used as the private key scalar. Since for 141 | EdDSA signing operations this seed value is needed, it is also stored 142 | within the private key.""" 143 | if seed is None: 144 | seed = secure_rand(curve.B // 8) 145 | assert(isinstance(seed, bytes)) 146 | assert(len(seed) == curve.B // 8) 147 | 148 | # Calculate hash over seed 149 | h = Tools.eddsa_hash(seed) 150 | 151 | # And generate scalar from hash over seed 152 | a = PrivKeyOpEDDSAKeyGen.__eddsa_bitstring(h, curve.p.bit_length()) 153 | 154 | # Conditioning may occur for some curves. Detect this by name for now. 155 | if curve.name == "ed25519": 156 | # Condition lower three bits to be cleared and bit 254 to be set 157 | a &= 0x3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8 158 | a |= 0x4000000000000000000000000000000000000000000000000000000000000000 159 | 160 | privkey = cls(a, curve) 161 | privkey.set_seed(seed) 162 | return privkey 163 | 164 | 165 | class PrivKeyOpEDDSAEncode(object): 166 | def eddsa_encode(self): 167 | """Performs serialization of a private key that is used for EdDSA.""" 168 | return self.seed 169 | 170 | @classmethod 171 | def eddsa_decode(cls, curve, encoded_privkey): 172 | """Performs decoding of a serialized private key as it is used for EdDSA.""" 173 | return cls.eddsa_generate(curve, encoded_privkey) 174 | 175 | class PrivKeyOpECDH(object): 176 | def ecdh_compute(self, peer_pubkey): 177 | """Compute the shared secret point using our own private key and the 178 | public key of our peer.""" 179 | return self.scalar * peer_pubkey.point 180 | 181 | -------------------------------------------------------------------------------- /construction-1/ecc/PubKeyOps.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | 3 | from .FieldElement import FieldElement 4 | from .AffineCurvePoint import AffineCurvePoint 5 | from .Random import secure_rand_int_between 6 | from . import Tools 7 | 8 | class PubKeyOpECDSAExploitReusedNonce(object): 9 | def ecdsa_exploit_reused_nonce(self, msg1, sig1, msg2, sig2): 10 | """Given two different messages msg1 and msg2 and their corresponding 11 | signatures sig1, sig2, try to calculate the private key that was used 12 | for signing if during signature generation no unique nonces were 13 | used.""" 14 | assert(isinstance(msg1, bytes)) 15 | assert(isinstance(msg2, bytes)) 16 | assert(msg1 != msg2) 17 | assert(sig1.r == sig2.r) 18 | 19 | # Hash the messages 20 | dig1 = hashlib.new(sig1.hashalg) 21 | dig1.update(msg1) 22 | dig1 = dig1.digest() 23 | dig2 = hashlib.new(sig2.hashalg) 24 | dig2.update(msg2) 25 | dig2 = dig2.digest() 26 | 27 | # Calculate hashes of messages 28 | e1 = Tools.ecdsa_msgdigest_to_int(dig1, self.point.curve.n) 29 | e2 = Tools.ecdsa_msgdigest_to_int(dig2, self.point.curve.n) 30 | 31 | # Take them modulo n 32 | e1 = FieldElement(e1, self.point.curve.n) 33 | e2 = FieldElement(e2, self.point.curve.n) 34 | 35 | (s1, s2) = (FieldElement(sig1.s, self.point.curve.n), FieldElement(sig2.s, self.point.curve.n)) 36 | r = sig1.r 37 | 38 | # Recover (supposedly) random nonce 39 | nonce = (e1 - e2) // (s1 - s2) 40 | 41 | # Recover private key 42 | priv = ((nonce * s1) - e1) // r 43 | 44 | return { "nonce": nonce, "privatekey": priv } 45 | 46 | 47 | class PubKeyOpECDSAVerify(object): 48 | def ecdsa_verify_hash(self, message_digest, signature): 49 | """Verify ECDSA signature over the hash of a message (the message 50 | digest).""" 51 | assert(isinstance(message_digest, bytes)) 52 | assert(0 < signature.r < self.curve.n) 53 | assert(0 < signature.s < self.curve.n) 54 | 55 | # Convert message digest to integer value 56 | e = Tools.ecdsa_msgdigest_to_int(message_digest, self.curve.n) 57 | 58 | (r, s) = (signature.r, FieldElement(signature.s, self.curve.n)) 59 | w = s.inverse() 60 | u1 = int(e * w) 61 | u2 = int(r * w) 62 | 63 | pt = (u1 * self.curve.G) + (u2 * self.point) 64 | x1 = int(pt.x) % self.curve.n 65 | return x1 == r 66 | 67 | def ecdsa_verify(self, message, signature): 68 | """Verify an ECDSA signature over a message.""" 69 | assert(isinstance(message, bytes)) 70 | digest_fnc = hashlib.new(signature.hashalg) 71 | digest_fnc.update(message) 72 | message_digest = digest_fnc.digest() 73 | return self.ecdsa_verify_hash(message_digest, signature) 74 | 75 | 76 | class PubKeyOpEDDSAVerify(object): 77 | def eddsa_verify(self, message, signature): 78 | """Verify an EdDSA signature over a message.""" 79 | h = Tools.bytestoint_le(Tools.eddsa_hash(signature.R.eddsa_encode() + self.point.eddsa_encode() + message)) 80 | return (signature.s * self.curve.G) == signature.R + (h * self.point) 81 | 82 | 83 | class PubKeyOpEDDSAEncode(object): 84 | def eddsa_encode(self): 85 | """Encodes a EdDSA-encoded public key to its serialized (bytes) 86 | form.""" 87 | return self.point.eddsa_encode() 88 | 89 | @classmethod 90 | def eddsa_decode(cls, curve, encoded_pubkey): 91 | """Decodes a EdDSA-encoded public key from its serialized (bytes) 92 | form.""" 93 | pubkey = AffineCurvePoint.eddsa_decode(curve, encoded_pubkey) 94 | return cls(pubkey) 95 | 96 | class PubKeyOpECIESEncrypt(object): 97 | def ecies_encrypt(self, r = None): 98 | """Generates a shared secret which can be used to symetrically encrypt 99 | data that only the holder of the corresponding private key can read. 100 | The output are two points, R and S: R is the public point that is 101 | transmitted together with the message while S is the point which 102 | resembles the shared secret. The receiver can use R together with her 103 | private key to reconstruct S. A random nonce r can be supplied for this 104 | function. If it isn't supplied, it is randomly chosen.""" 105 | 106 | # Chose a random number 107 | if r is None: 108 | r = secure_rand_int_between(1, self.curve.n - 1) 109 | 110 | R = r * self.curve.G 111 | S = r * self.point 112 | 113 | # Return the publicly transmitted R and the symmetric key S 114 | return { "R": R, "S": S } 115 | 116 | -------------------------------------------------------------------------------- /construction-1/ecc/Random.py: -------------------------------------------------------------------------------- 1 | # 2 | # joeecc - A small Elliptic Curve Cryptography Demonstration. 3 | # Copyright (C) 2011-2015 Johannes Bauer 4 | # 5 | # This file is part of joeecc. 6 | # 7 | # joeecc is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; this program is ONLY licensed under 10 | # version 3 of the License, later versions are explicitly excluded. 11 | # 12 | # joeecc is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with joeecc; if not, write to the Free Software 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | # 21 | # Johannes Bauer 22 | # 23 | 24 | def secure_rand(length): 25 | f = open("/dev/urandom", "rb") 26 | data = f.read(length) 27 | assert(len(data) == length) 28 | f.close() 29 | return data 30 | 31 | 32 | def secure_rand_int(max_value): 33 | """Yields a value 0 <= return < maxvalue.""" 34 | assert(max_value >= 2) 35 | bytecnt = ((max_value - 1).bit_length() + 7) // 8 36 | max_bin_value = 256 ** bytecnt 37 | wholecnt = max_bin_value // max_value 38 | cutoff = wholecnt * max_value 39 | while True: 40 | rnd = sum((value << (8 * bytepos)) for (bytepos, value) in enumerate(secure_rand(bytecnt))) 41 | if rnd < cutoff: 42 | break 43 | return rnd % max_value 44 | 45 | def secure_rand_int_between(min_value, max_value): 46 | """Yields a random number which goes from min_value (inclusive) to 47 | max_value (inclusive).""" 48 | return secure_rand_int(max_value - min_value + 1) + min_value 49 | 50 | -------------------------------------------------------------------------------- /construction-1/ecc/ShortWeierstrassCurve.py: -------------------------------------------------------------------------------- 1 | # 2 | # joeecc - A small Elliptic Curve Cryptography Demonstration. 3 | # Copyright (C) 2011-2015 Johannes Bauer 4 | # 5 | # This file is part of joeecc. 6 | # 7 | # joeecc is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; this program is ONLY licensed under 10 | # version 3 of the License, later versions are explicitly excluded. 11 | # 12 | # joeecc is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with joeecc; if not, write to the Free Software 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | # 21 | # Johannes Bauer 22 | # 23 | 24 | import collections 25 | from .FieldElement import FieldElement 26 | from .AffineCurvePoint import AffineCurvePoint 27 | from .EllipticCurve import EllipticCurve 28 | 29 | _ShortWeierstrassCurveDomainParameters = collections.namedtuple("ShortWeierstrassCurveDomainParameters", [ "curvetype", "a", "b", "p", "n", "h", "G" ]) 30 | 31 | class ShortWeierstrassCurve(EllipticCurve): 32 | """Represents an elliptic curve over a finite field F_P that satisfies the 33 | short Weierstrass equation y^2 = x^3 + ax + b.""" 34 | 35 | def __init__(self, a, b, p, n, h, Gx, Gy, **kwargs): 36 | """Create an elliptic curve given the equation coefficients a and b, 37 | the curve modulus p, the order of the curve n, the cofactor of the 38 | curve h and the generator point G's X and Y coordinates in affine 39 | representation, Gx and Gy.""" 40 | EllipticCurve.__init__(self) 41 | assert(isinstance(a, int)) # Curve coefficent A 42 | assert(isinstance(b, int)) # Curve coefficent B 43 | assert(isinstance(p, int)) # Modulus 44 | assert(isinstance(n, int)) # Order 45 | assert(isinstance(h, int)) # Cofactor 46 | assert((Gx is None) or isinstance(Gx, int)) # Generator Point X 47 | assert((Gy is None) or isinstance(Gy, int)) # Generator Point Y 48 | self._a = FieldElement(a, p) 49 | self._b = FieldElement(b, p) 50 | self._p = p 51 | self._n = n 52 | self._h = h 53 | self._name = kwargs.get("name") 54 | 55 | # Check that the curve is not singular 56 | assert((4 * (self.a ** 3)) + (27 * (self.b ** 2)) != 0) 57 | 58 | if (Gx is not None) or (Gy is not None): 59 | # Check that the generator G is on the curve 60 | self._G = AffineCurvePoint(Gx, Gy, self) 61 | assert(self._G.oncurve()) 62 | 63 | # Check that the generator G is of curve order 64 | assert((self.n * self.G).is_neutral) 65 | else: 66 | self._G = None 67 | 68 | @property 69 | def domainparams(self): 70 | return _ShortWeierstrassCurveDomainParameters(curvetype = self.curvetype, a = self.a, b = self.d, p = self.p, n = self.n, h = self.h, G = self.G) 71 | 72 | @property 73 | def curvetype(self): 74 | return "shortweierstrass" 75 | 76 | @property 77 | def a(self): 78 | return self._a 79 | 80 | @property 81 | def b(self): 82 | return self._b 83 | 84 | @property 85 | def p(self): 86 | return self._p 87 | 88 | @property 89 | def n(self): 90 | return self._n 91 | 92 | @property 93 | def h(self): 94 | return self._h 95 | 96 | @property 97 | def G(self): 98 | return self._G 99 | 100 | def getpointwithx(self, x): 101 | assert(isinstance(x, int)) 102 | yy = ((FieldElement(x, self._p) ** 3) + (self._a * x) + self._b) 103 | y = yy.sqrt() 104 | if y: 105 | return (AffineCurvePoint(x, int(y[0]), self), AffineCurvePoint(x, int(y[1]), self)) 106 | else: 107 | return None 108 | 109 | def oncurve(self, P): 110 | return P.is_neutral or ((P.y ** 2) == (P.x ** 3) + (self.a * P.x) + self.b) 111 | 112 | def point_conjugate(self, P): 113 | return AffineCurvePoint(int(P.x), int(-P.y), self) 114 | 115 | def point_addition(self, P, Q): 116 | if P.is_neutral: 117 | # P is at infinity, O + Q = Q 118 | result = Q 119 | elif Q.is_neutral: 120 | # Q is at infinity, P + O = P 121 | result = P 122 | elif P == -Q: 123 | # P == -Q, return O (point at infinity) 124 | result = self.neutral() 125 | elif P == Q: 126 | # P == Q, point doubling 127 | s = ((3 * P.x ** 2) + self.a) // (2 * P.y) 128 | newx = s * s - (2 * P.x) 129 | newy = s * (P.x - newx) - P.y 130 | result = AffineCurvePoint(int(newx), int(newy), self) 131 | else: 132 | # P != Q, point addition 133 | s = (P.y - Q.y) // (P.x - Q.x) 134 | newx = (s ** 2) - P.x - Q.x 135 | newy = s * (P.x - newx) - P.y 136 | result = AffineCurvePoint(int(newx), int(newy), self) 137 | return result 138 | 139 | def compress(self, P): 140 | #Fixed bug to support neutral 141 | if P.is_neutral: 142 | return (0, 3) 143 | #return (int(P.x), int(P.y) % 2) 144 | else: 145 | return (int(P.x), int(P.y) % 2) 146 | #print(P) 147 | 148 | def uncompress(self, compressed): 149 | #Fixed bug to support neutral 150 | (x, ybit) = compressed 151 | if ybit == 3: 152 | return self.neutral() 153 | else: 154 | x = FieldElement(x, self.p) 155 | alpha = (x ** 3) + (self.a * x) + self.b 156 | (beta1, beta2) = alpha.sqrt() 157 | if (int(beta1) % 2) == ybit: 158 | y = beta1 159 | else: 160 | y = beta2 161 | return AffineCurvePoint(int(x), int(y), self) 162 | 163 | def enumerate_points(self): 164 | yield self.neutral() 165 | for x in range(self.p): 166 | points = self.getpointwithx(x) 167 | if points is not None: 168 | yield points[0] 169 | yield points[1] 170 | 171 | def __str__(self): 172 | if self.hasname: 173 | return "ShortWeierstrassCurve<%s>" % (self.name) 174 | else: 175 | return "ShortWeierstrassCurve" % (int(self.a), int(self.b), int(self.p)) 176 | -------------------------------------------------------------------------------- /construction-1/ecc/Singleton.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # 3 | # Singleton - Singleton decorator, taken from PEP318 4 | # Copyright (C) 2011-2012 Johannes Bauer 5 | # 6 | # This file is part of jpycommon. 7 | # 8 | # jpycommon is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; this program is ONLY licensed under 11 | # version 3 of the License, later versions are explicitly excluded. 12 | # 13 | # jpycommon is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with jpycommon; if not, write to the Free Software 20 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 | # 22 | # Johannes Bauer 23 | # 24 | # File UUID a24a2230-7bd4-4737-98ab-8aae62d1bd57 25 | 26 | def singleton(cls): 27 | class InnerClass(cls): 28 | _instance = None 29 | 30 | def __new__(cls, *args, **kwargs): 31 | if InnerClass._instance is None: 32 | InnerClass._instance = super(InnerClass, cls).__new__(cls, *args, **kwargs) 33 | InnerClass._instance._initialized = False 34 | return InnerClass._instance 35 | 36 | def __init__(self, *args, **kwargs): 37 | if self._initialized: 38 | return 39 | super(InnerClass, self).__init__(*args, **kwargs) 40 | self._initialized = True 41 | 42 | InnerClass.__name__ = cls.__name__ 43 | return InnerClass 44 | 45 | 46 | if __name__ == "__main__": 47 | print("start") 48 | 49 | @singleton 50 | class FooSingleton(): 51 | _barkoo = -1 52 | 53 | def __init__(self): 54 | print("init called") 55 | 56 | def getid(self): 57 | return id(self) * FooSingleton._barkoo 58 | 59 | print("pre init") 60 | x = FooSingleton() 61 | print(x, x.getid()) 62 | 63 | y = FooSingleton() 64 | print(y, y.getid()) 65 | 66 | z = FooSingleton() 67 | print(z, z.getid()) 68 | 69 | assert(x is y) 70 | -------------------------------------------------------------------------------- /construction-1/ecc/Tools.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | 3 | def bytestoint(data): 4 | """Converts given bytes to a big-endian integer value.""" 5 | return sum(value << (8 * index) for (index, value) in enumerate(reversed(data))) 6 | 7 | def bytestoint_le(data): 8 | """Converts given bytes to a little-endian integer value.""" 9 | return sum(value << (8 * index) for (index, value) in enumerate(data)) 10 | 11 | def inttobytes_le(value, length): 12 | """Converts a little-endian integer value into a bytes object.""" 13 | return bytes((value >> (8 * i)) & 0xff for i in range(length)) 14 | 15 | def ecdsa_msgdigest_to_int(message_digest, curveorder): 16 | """Performs truncation of a message digest to the bitlength of the curve 17 | order.""" 18 | # Convert message digest to integer value 19 | e = bytestoint(message_digest) 20 | 21 | # Truncate hash value if necessary 22 | msg_digest_bits = 8 * len(message_digest) 23 | if msg_digest_bits > curveorder.bit_length(): 24 | shift = msg_digest_bits - curveorder.bit_length() 25 | e >>= shift 26 | 27 | return e 28 | 29 | def eddsa_hash(data): 30 | """Returns the message digest over the data which is used for EdDSA 31 | (SHA-512).""" 32 | return hashlib.sha512(data).digest() 33 | 34 | -------------------------------------------------------------------------------- /construction-1/ecc/TwistedEdwardsCurve.py: -------------------------------------------------------------------------------- 1 | # 2 | # joeecc - A small Elliptic Curve Cryptography Demonstration. 3 | # Copyright (C) 2011-2015 Johannes Bauer 4 | # 5 | # This file is part of joeecc. 6 | # 7 | # joeecc is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; this program is ONLY licensed under 10 | # version 3 of the License, later versions are explicitly excluded. 11 | # 12 | # joeecc is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with joeecc; if not, write to the Free Software 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | # 21 | # Johannes Bauer 22 | # 23 | 24 | import collections 25 | from .FieldElement import FieldElement 26 | from .AffineCurvePoint import AffineCurvePoint 27 | from .EllipticCurve import EllipticCurve 28 | import ecc.MontgomeryCurve 29 | 30 | _TwistedEdwardsCurveDomainParameters = collections.namedtuple("TwistedEdwardsCurveDomainParameters", [ "curvetype", "a", "d", "p", "n", "G" ]) 31 | 32 | class TwistedEdwardsCurve(EllipticCurve): 33 | """Represents an elliptic curve over a finite field F_P that satisfies the 34 | Twisted Edwards equation a x^2 + y^2 = 1 + d x^2 y^2.""" 35 | 36 | def __init__(self, a, d, p, n, h, Gx, Gy, **kwargs): 37 | """Create an elliptic Twisted Edwards curve given the equation 38 | coefficients a and d, the curve field's modulus p, the order of the 39 | curve n and the generator point G's X and Y coordinates in affine 40 | representation, Gx and Gy.""" 41 | EllipticCurve.__init__(self) 42 | assert(isinstance(a, int)) # Curve coefficent A 43 | assert(isinstance(d, int)) # Curve coefficent D 44 | assert(isinstance(p, int)) # Modulus 45 | assert(isinstance(n, int)) # Order 46 | assert(isinstance(h, int)) # Cofactor 47 | assert((Gx is None) or isinstance(Gx, int)) # Generator Point X 48 | assert((Gy is None) or isinstance(Gy, int)) # Generator Point Y 49 | self._a = FieldElement(a, p) 50 | self._d = FieldElement(d, p) 51 | self._p = p 52 | self._n = n 53 | self._h = h 54 | self._name = kwargs.get("name") 55 | 56 | # Check that the curve is not singular 57 | assert(self.d * (1 - self.d) != 0) 58 | 59 | if (Gx is not None) or (Gy is not None): 60 | # Check that the generator G is on the curve 61 | self._G = AffineCurvePoint(Gx, Gy, self) 62 | assert(self._G.oncurve()) 63 | 64 | # Check that the generator G is of curve order 65 | assert((self.n * self.G).is_neutral) 66 | else: 67 | self._G = None 68 | 69 | @property 70 | def domainparams(self): 71 | return _TwistedEdwardsCurveDomainParameters(curvetype = self.curvetype, a = self.a, d = self.d, p = self.p, n = self.n, G = self.G) 72 | 73 | @property 74 | def curvetype(self): 75 | return "twistededwards" 76 | 77 | @property 78 | def a(self): 79 | return self._a 80 | 81 | @property 82 | def d(self): 83 | return self._d 84 | 85 | @property 86 | def p(self): 87 | return self._p 88 | 89 | @property 90 | def n(self): 91 | return self._n 92 | 93 | @property 94 | def h(self): 95 | return self._h 96 | 97 | @property 98 | def G(self): 99 | return self._G 100 | 101 | @property 102 | def B(self): 103 | """Returns the length of the curve's field modulus in bits plus one.""" 104 | return self._p.bit_length() + 1 105 | 106 | @property 107 | def is_complete(self): 108 | """Returns if the twisted Edwards curve is complete. This is the case 109 | exactly when d is a quadratic non-residue modulo p.""" 110 | return self.d.is_qnr 111 | 112 | def neutral(self): 113 | return AffineCurvePoint(0, 1, self) 114 | 115 | def is_neutral(self, P): 116 | return (P.x == 0) and (P.y == 1) 117 | 118 | def oncurve(self, P): 119 | return (self.a * P.x ** 2) + P.y ** 2 == 1 + self.d * P.x ** 2 * P.y ** 2 120 | 121 | def point_conjugate(self, P): 122 | return AffineCurvePoint(int(-P.x), int(P.y), self) 123 | 124 | def point_addition(self, P, Q): 125 | x = (P.x * Q.y + Q.x * P.y) // (1 + self.d * P.x * Q.x * P.y * Q.y) 126 | y = (P.y * Q.y - self.a * P.x * Q.x) // (1 - self.d * P.x * Q.x * P.y * Q.y) 127 | return AffineCurvePoint(int(x), int(y), self) 128 | 129 | def to_montgomery(self, b = None): 130 | """Converts the twisted Edwards curve domain parameters to Montgomery 131 | domain parameters. For this conversion, b can be chosen semi-freely. 132 | If the native b coefficient is a quadratic residue modulo p, then the 133 | freely chosen b value must also be. If it is a quadratic non-residue, 134 | then so must be the surrogate b coefficient. If b is omitted, the 135 | native b value is used. The generator point of the twisted Edwards 136 | curve is also converted to Montgomery form. For this conversion, 137 | there's an invariant (one of two possible outcomes). An arbitrary 138 | bijection is used for this.""" 139 | assert((b is None) or isinstance(b, int)) 140 | 141 | # Calculate the native montgomery coefficents a, b first 142 | a = 2 * (self.a + self.d) // (self.a - self.d) 143 | native_b = 4 // (self.a - self.d) 144 | if b is None: 145 | b = native_b 146 | else: 147 | # If a b value was supplied, make sure is is either a QR or QNR mod 148 | # p, depending on what the native b value was 149 | b = FieldElement(b, self.p) 150 | if native_b.is_qr != b.is_qr: 151 | raise Exception("The b coefficient of the resulting curve must be a quadratic %s modulo p, %s is not." % ([ "non-residue", "residue" ][native_b.is_qr], str(b))) 152 | 153 | # Generate the raw curve without a generator yet 154 | raw_curve = ecc.MontgomeryCurve.MontgomeryCurve( 155 | a = int(a), 156 | b = int(b), 157 | p = self.p, 158 | n = self.n, 159 | h = self.h, 160 | Gx = None, 161 | Gy = None, 162 | ) 163 | 164 | # Then convert the original generator point using the raw curve to 165 | # yield a birationally equivalent generator point 166 | G_m = self.G.convert(raw_curve) 167 | 168 | # And create the curve again, setting this generator 169 | montgomery_curve = ecc.MontgomeryCurve.MontgomeryCurve( 170 | a = int(a), 171 | b = int(b), 172 | p = self.p, 173 | n = self.n, 174 | h = self.h, 175 | Gx = int(G_m.x), 176 | Gy = int(G_m.y), 177 | ) 178 | 179 | return montgomery_curve 180 | 181 | def __str__(self): 182 | if self.hasname: 183 | return "TwistedEdwardsCurve<%s>" % (self.name) 184 | else: 185 | return "TwistedEdwardsCurve<0x%x x^2 + y^2 = 1 + 0x%x x^2 y^2 mod 0x%x>" % (int(self.a), int(self.d), int(self.p)) 186 | 187 | -------------------------------------------------------------------------------- /construction-1/ecc/__init__.py: -------------------------------------------------------------------------------- 1 | """joeecc - Elliptic Curve Cryptography demonstration library 2 | 3 | joeecc is a library that is supposed to demonstrate and teach how Elliptic 4 | Curve Cryptography (ECC) works. It is implemented in pure Python and neither 5 | aims to be feature-complete not side-channel resistant not secure in any way. 6 | Please keep this in mind when using joeecc. 7 | 8 | There is a curve database included in joeecc which already knows lots of 9 | interesting elliptic curves by name: 10 | 11 | import ecc 12 | curve = ecc.getcurvebyname("secp112r1") 13 | print(curve) 14 | ShortWeierstrassCurve 15 | 16 | On this curve you can now create a public/private keypair: 17 | 18 | privkey = ecc.ECPrivateKey.generate(curve) 19 | print(privkey) 20 | PrivateKey 21 | print(privkey.pubkey) 22 | PublicKey<(0x69976db41f5e487928463b9f8a38, 0xda1fdba3de89c58683bd2d635430)> 23 | 24 | You can also regenerate this keypair later on if you wish to remain it static 25 | and not change with every invocation: 26 | 27 | privkey = ecc.ECPrivateKey(0x89fb9821aa5154c9934b3e0268ef, curve) 28 | print(privkey) 29 | PrivateKey 30 | 31 | You can use this keypair to perform actions like ECDSA signing: 32 | 33 | signature = privkey.ecdsa_sign(b"Foobar", "sha1") 34 | print(signature) 35 | ECDSASignature(hashalg='sha1', r=1762251013383878369191057972852867, s=3691758261134002001156831324480002) 36 | 37 | If you want to recreate a public key anew, you can also do so by first creating 38 | the public point: 39 | 40 | pubkeypt = ecc.AffineCurvePoint(0x69976db41f5e487928463b9f8a38, 0xda1fdba3de89c58683bd2d635430, curve) 41 | print(pubkeypt) 42 | (0x69976db41f5e487928463b9f8a38, 0xda1fdba3de89c58683bd2d635430) 43 | 44 | Then you can just wrap the point in a ECPublicKey object to have access to 45 | methods like ECDSA verification and such: 46 | 47 | pubkey = ecc.ECPublicKey(pubkeypt) 48 | print(pubkey) 49 | PublicKey<(0x69976db41f5e487928463b9f8a38, 0xda1fdba3de89c58683bd2d635430)> 50 | 51 | Lastly, you can verify the signature you created earlier: 52 | 53 | pubkey.ecdsa_verify(b"Foobar", signature) 54 | True 55 | 56 | And change the message so the signature would become invalid: 57 | 58 | pubkey.ecdsa_verify(b"Barfoo", signature) 59 | False 60 | """ 61 | 62 | # 63 | # joeecc - A small Elliptic Curve Cryptography Demonstration. 64 | # Copyright (C) 2011-2015 Johannes Bauer 65 | # 66 | # This file is part of joeecc. 67 | # 68 | # joeecc is free software; you can redistribute it and/or modify 69 | # it under the terms of the GNU General Public License as published by 70 | # the Free Software Foundation; this program is ONLY licensed under 71 | # version 3 of the License, later versions are explicitly excluded. 72 | # 73 | # joeecc is distributed in the hope that it will be useful, 74 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 75 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 76 | # GNU General Public License for more details. 77 | # 78 | # You should have received a copy of the GNU General Public License 79 | # along with joeecc; if not, write to the Free Software 80 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 81 | # 82 | # Johannes Bauer 83 | # 84 | 85 | from .FieldElement import FieldElement 86 | from .AffineCurvePoint import AffineCurvePoint 87 | from .CurveDB import getcurvedb, getcurvebyname, getcurvenames 88 | from .ECPrivateKey import ECPrivateKey 89 | from .ECPublicKey import ECPublicKey 90 | 91 | -------------------------------------------------------------------------------- /construction-1/ecc/tests/CryptoOpsTests.py: -------------------------------------------------------------------------------- 1 | # 2 | # joeecc - A small Elliptic Curve Cryptography Demonstration. 3 | # Copyright (C) 2011-2015 Johannes Bauer 4 | # 5 | # This file is part of joeecc. 6 | # 7 | # joeecc is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; this program is ONLY licensed under 10 | # version 3 of the License, later versions are explicitly excluded. 11 | # 12 | # joeecc is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with joeecc; if not, write to the Free Software 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | # 21 | # Johannes Bauer 22 | # 23 | 24 | import unittest 25 | from .. import getcurvebyname, getcurvenames 26 | from ..ECPrivateKey import ECPrivateKey 27 | 28 | class CryptoOpsTests(unittest.TestCase): 29 | def test_curve_integrity(self): 30 | for curvename in getcurvenames(): 31 | curve = getcurvebyname(curvename) 32 | self.assertTrue(curve.G.oncurve()) 33 | 34 | def test_simple_sign_verify(self): 35 | curve = getcurvebyname("secp112r1") 36 | privkey = ECPrivateKey(0xdeadbeef, curve) 37 | self.assertEqual(int(privkey.pubkey.point.x), 3029259716094196738484362740763961) 38 | self.assertEqual(int(privkey.pubkey.point.y), 2918181739692718713384134377830669) 39 | 40 | msg = b"foobar" 41 | signature = privkey.ecdsa_sign(msg, "sha1", k = 12345) 42 | self.assertEqual(signature.s, 1960761230049936699759766101723490) 43 | self.assertEqual(signature.r, 1696427335541514286367855701829018) 44 | 45 | self.assertTrue(privkey.pubkey.ecdsa_verify(msg, signature)) 46 | 47 | def test_openssl_signature(self): 48 | curve = getcurvebyname("prime239v1") 49 | msg = b"foobar" 50 | r = 0x76EAA8341A6E30FE72C87343A50DD2BBE472CF5E5A394D245DF354EF11CD 51 | s = 0x0304117012F37FC316D9030E456F53940008C7FAF569BBE6E5B4AA1A2D40 52 | hashalg = "sha256" 53 | 54 | privkeystr = "6e:29:dc:d3:c4:7c:a3:3c:3d:0e:f5:3a:15:14:18:ff:ff:9b:44:dc:26:21:ac:d3:fc:ac:ca:5b:c8:f2" 55 | privkeyint = int(privkeystr.replace(":", ""), 16) 56 | privkey = ECPrivateKey(privkeyint, curve) 57 | self.assertEqual(privkey.pubkey.point.x, 0x0f5e2baa05719806cbdb133d438011efc2c4e036d59cb799fa87d2ecab97) 58 | self.assertEqual(privkey.pubkey.point.y, 0x56fd18e031e2869a872bbc96ec473bd5eb2e9a22a2e246bd00ed0491fdde) 59 | 60 | signature = ECPrivateKey.ECDSASignature(r = r, s = s, hashalg = hashalg) 61 | self.assertTrue(privkey.pubkey.ecdsa_verify(msg, signature)) 62 | 63 | def test_ecies(self): 64 | curve = getcurvebyname("secp112r1") 65 | privkey = ECPrivateKey.generate(curve) 66 | 67 | encparams = privkey.pubkey.ecies_encrypt() 68 | S = privkey.ecies_decrypt(encparams["R"]) 69 | self.assertEqual(S, encparams["S"]) 70 | 71 | 72 | def test_ecdh(self): 73 | curve = getcurvebyname("secp112r1") 74 | 75 | party1_privkey = ECPrivateKey.generate(curve) 76 | party2_privkey = ECPrivateKey.generate(curve) 77 | 78 | 79 | S1 = party1_privkey.ecdh_compute(party2_privkey.pubkey) 80 | S2 = party2_privkey.ecdh_compute(party1_privkey.pubkey) 81 | self.assertEqual(S1, S2) 82 | -------------------------------------------------------------------------------- /construction-1/ecc/tests/CurveTests.py: -------------------------------------------------------------------------------- 1 | # 2 | # joeecc - A small Elliptic Curve Cryptography Demonstration. 3 | # Copyright (C) 2011-2015 Johannes Bauer 4 | # 5 | # This file is part of joeecc. 6 | # 7 | # joeecc is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; this program is ONLY licensed under 10 | # version 3 of the License, later versions are explicitly excluded. 11 | # 12 | # joeecc is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with joeecc; if not, write to the Free Software 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | # 21 | # Johannes Bauer 22 | # 23 | 24 | import unittest 25 | import random 26 | from .. import getcurvebyname 27 | 28 | class CurveTests(unittest.TestCase): 29 | _TEST_POINTS = { 30 | "curve25519": { 31 | 1: (9, 43114425171068552920764898935933967039370386198203806730763910166200978582548), 32 | 2: (14847277145635483483963372537557091634710985132825781088887140890597596352251, 48981431527428949880507557032295310859754924433568441600873610210018059225738), 33 | 3: (12697861248284385512127539163427099897745340918349830473877503196793995869202, 39113539887452079713994524130201898724087778094240617142109147539155741236674), 34 | 123456789: (30376724422097943771464932184814037210568590291263477766440708946546190417432, 33978466996746720392480166239534270758276883276344012864085150459987743884642), 35 | 483298430288343589: (4786491578210548115045114306563336510283917938320881491936873603578866593690, 53686050085367235225771646963246356156258608564759608957840655026958629717344), 36 | }, 37 | "ed25519": { 38 | 0: (0x0, 0x1), 39 | 1: (0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a, 0x6666666666666666666666666666666666666666666666666666666666666658), 40 | 2: (0x36ab384c9f5a046c3d043b7d1833e7ac080d8e4515d7a45f83c5a14e2843ce0e, 0x2260cdf3092329c21da25ee8c9a21f5697390f51643851560e5f46ae6af8a3c9), 41 | 3: (0x67ae9c4a22928f491ff4ae743edac83a6343981981624886ac62485fd3f8e25c, 0x1267b1d177ee69aba126a18e60269ef79f16ec176724030402c3684878f5b4d4), 42 | 123456789: (0x547df969eeaad777ccc47f172eb04d76d148ac6fe7e6f03c5f764f1e15327545, 0x5bd3c1a4f2053b458e38123b41e36ddeb5d13a6f63365d93e90ddc6880adff17), 43 | 0x55aa55aa: (0x3aabbf7c82aa6bd17fbc24c0e701348f3dde1252a68302fb01a43058abc1bae5, 0x24f569c61916a6a639aa15b71e19d3d4dd1843c742bdd6be1bf0faed7ff3208f), 44 | 4: (0x203da8db56cff1468325d4b87a3520f91a739ec193ce1547493aa657c4c9f870, 0x47d0e827cb1595e1470eb88580d5716c4cf22832ea2f0ff0df38ab61ca32112f), 45 | 5: (0x49fda73eade3587bfcef7cf7d12da5de5c2819f93e1be1a591409cc0322ef233, 0x5f4825b298feae6fe02c6e148992466631282eca89430b5d10d21f83d676c8ed), 46 | 6: (0x4c9797ba7a45601c62aeacc0dd0a29bea1e599826c7b4427783a741a7dcbf23d, 0x54de3fc2886d8a11db709a7fd4f7d77f9417c06944d6b60c1d27ad0f9497ef4), 47 | 7: (0x14568685fcf4bd4ee9e3ee194b1d810783e809f3bbf1ce955855981af50e4107, 0x31c563e32b47d52f87ce6468dd36ad41f0882b46f7abf23d12c4c4b59f4062b8), 48 | 8: (0x6742e15f97d771b642862d5cf84ecf93eb3ac67b80698b993b87fdbc08a584c8, 0x21d30600c9e573796ead6f09668af38f81783cfc621ee4931e2f5ba9fc37b9b4), 49 | 9: (0x357cc970c80071651bf336e06f9422b886d80e5c2e4e0294d3e023065185715c, 0x7f3d23c2c2dd0df4b2befce956f2d2fd1f789013236e4430c74e44845522f1c0), 50 | 10: (0x602c797e30ca6d754470b60ed2bc8677207e8e4ed836f81444951f224877f94f, 0x637ffcaa7a1b2477c8e44d54c898bfcf2576a6853de0e843ba8874b06ae87b2c), 51 | 11: (0x14e528b1154be417b6cf078dd6712438d381a5b2c593d552ff2fd2c1207cf3cb, 0x2d9082313f21ab975a6f7ce340ff0fce1258591c3c9c58d4308f2dc36a033713), 52 | 12: (0x4719e17e016e5d355ecf70e00ca249db3295bf2385c13b42ae62fe6678f0902d, 0x4070ce608bce8022e71d6c4e637825b856487eb45273966733d281dc2e2de4f9), 53 | 13: (0x107427e0d5f366ccdb33adf0282d304f8843e3e88d22b7b83780e073b7c05fed, 0x12dbb00ded538b7478466022d2da89b83740cfb2289a272387efe1aeea401f80), 54 | 14: (0x205f3b42f5884aaf048c7a895ccabb15d8dee6d83e39832aa38e7353b58515b9, 0x4e50256f50c4cb8115bad17acbb702bfa74898e819b6265c8369fd98899c2839), 55 | 15: (0x4f162deaec2ec435dc5ac6f95d20419ed9631374770189cb90617f3e66a18dc1, 0x12cbfb2d04ff22f55162f70164d29331ace5af18a19a9aa1946d4cc4ad2e5cdf), 56 | 16: (0x23a4860627e53aeeb8e22b1508249c9109578d33e7bf237459b2596d6c28f9f8, 0x709696f2827fc3729f980f2e3aad6e78b06a11ff8e079c27d87aab37c16727eb), 57 | 17: (0x7dc52d5a7db816e9b850741ea2fd72918d94985b85a20b4dc5597853a876df6a, 0x6f6d2bca60003ef9f24ac245cc919fb717b188723b34f901cd6cfe9bec97be04), 58 | 18: (0x1368877f4867292aaf9c0393bc2b0e869158987876b8001297b644a64bb10b96, 0x2e1126847e0bd8987de8e8ea8a96c3a5bc810e4ed6d496b0354e3e90e075b04a), 59 | 19: (0x1d81f74a5ba45c7022e8c140d763b9c1b0e281a5304696e74f791a3a04a94472, 0x3f185a93d95a4347227c5bb6ddd65cf42e1830823f435f3083fe6102691d55b9), 60 | 20: (0x673c65caedd698b94f5bbd757df73a9e6985150ecd4a2135a058e273ab4cf9af, 0x136cebacb6260a9d5e6a3e3171c535f0be71cfbe16a960b9dd317bda6f3c5a38), 61 | 21: (0x6f0ac78e5eb90e87958588f9d47541edf252cb1dde3d073cc45e3e7ef9365716, 0x6628d116b7975ae5f323e5ddf4f8cc35ae06d5c5c7d8a56effc66051336d289e), 62 | 22: (0x1e029b938c915f04b0c73d7338516ad51e376a9afa7de7c8c077622c2aec2f7a, 0x6bfc9472cde96427c4ac03f52e0d2b3cdce6566535dcee5a85a6a44b8975f24), 63 | 23: (0x2188ac423c67db5625915e05222a391bcaf91f05d9b7cc2cab5798b2d2e14d95, 0x23240c559c57b79a4df69a23fc46e50504277b1fa49369ab663d79782b33c0ee), 64 | 24: (0x70985f28875d4006e0968d9c952d799e610ed8e052a9a10e9677c71ee8886b81, 0x604e1b93c877b9896dca33cf8a2093cddf9fd21208c20d08e7b2444fed7b79f1), 65 | 25: (0x794241471ed9ceb009384b370cb8790fca98552ecb822dc06b19362c36353455, 0x71e918c03cdfca7207772e8d18ee8f9d92d79a0a83f378912362bc68d311dcd0), 66 | 26: (0x7982f658573d3d2519905e0d62c9469b667197fd602c7be16d5aa882178d4e9, 0x6c66e7e8eab0cfc9e9a180a04d91d6e5c9709380b7d63eb011dfe9afa1fa1a0c), 67 | 27: (0x163bc180c22dfc5da23c5c052107bba93a88b4360aa1d4e729611d8f5a7f8079, 0x631107a6ba83f7458194b9766a0a54f638ca20daf800384dbae1498677501939), 68 | 28: (0x47827fc68c31ec77e418a77ed5281a3c85bdbab18d755b18bcdf5b549748291, 0x7324ec33cef7b3ea9331141ae90f02866ce1bcfcdcd8c2d0191002f02078f0bb), 69 | 29: (0x39a32a30f3eb1da0eb7e3903b8ace3da3890b24b61a3a9e79db663b5db0f7a5d, 0x4d4c54675dc1f1c9a1af9ca0010045dc803c16af345823136dd203715d67c491), 70 | 30: (0x7e40e656adbd6aa0cb203f337dd19d441336400f59e341c837ebd71b7881e1e4, 0x342740ff1d2cc47aefed1e9b1c1b387cad3ff6f842729e20a414557407d2f3e4), 71 | 31: (0x38085391a0e2831f59c33fcce7591515784d359925f11ff958e0e4658efac0e9, 0x42918001a829f49b5634e34ab7fac21b30e24660669ed91955cc31944a19e62a), 72 | 32: (0x39cf6c6917421af98582561d0b39567de6033190f97852fc4fdd40f6977e4f26, 0x4434a90ee12cce6b7ade93ecc0f88b78b41205e74c8c4038f92d394f3a06d269), 73 | 33: (0x5e3573b049d6135ffbbbbd9a480617434f2455b4a591f719e91153eeb75a32a1, 0x54bc665420c789da1105d53983c1a0fc33bcc2690cd9b37d6566e21a85892871), 74 | 34: (0x43b314af3fad092a519dd4c1e4d90f6e6909eee8d3f9e99ca245db9d4de0a886, 0xaebdaf9a47afa9625f4a71b1f2d9b79da982c3139dbdbe3dbefa92d62333393), 75 | 100: (0x4b87a1147457b111116b878cfc2312de451370ac38fe8690876ef6ac346fd47, 0x405ea0cdd414bda960318b3108769a8928a25b756c372b254c69c78ea2fd81c5), 76 | 256: (0x5e7e07ed4e1decbfe6e9cbc126905449d4b578fbb561576d20b8bcdd0cc2a556, 0xf55755c51f102796bf5ebaa81d3260e7d1b3d9ac127d9a80e142031566cf6c7), 77 | 1000: (0x7d729f34487672ba293b953eaf0c41221c762b90f195f8e13e0e76abef68ce7e, 0xee1a16689ad85c7246c61a7192b28ba997c449bc5fe43aeaf943a3783aacae7), 78 | 4096: (0x7d13c0248b891b47eb524f2692008e2f97b199bac426cb5902b9003a29ded6ea, 0x59a976ab2c01a81a91f1a56c75ccc77a9e1e9e878e9fe9c3952080a6805b20d5), 79 | 89478485: (0x16d82ba2233fffa25a66fbf5da00bd6e761ecb5128e8404df22a0be5295a0a79, 0x5701ebcb79787ef64057ee32ee5bf0e1e127d7a082b79bd0a4c1dd6bd247052), 80 | 178956970: (0x6d6f8c2593b33ca1ccd705ed3b722645b6204f7693d98ff131767df19cf7cc65, 0x7bf3279fe978d59fd7a869995107b50fe64d00e7fd17b97ff5b73b05d4256141), 81 | 269488144: (0x5b4637afc2317d0549781d2aa9febdfa2be765e1352dd63c328da9c4bb7cd014, 0x518e8a42479c4ea248d963342f85968be9c75766689483cd404f5ab9f1e6f7eb), 82 | 1437226410: (0x3aabbf7c82aa6bd17fbc24c0e701348f3dde1252a68302fb01a43058abc1bae5, 0x24f569c61916a6a639aa15b71e19d3d4dd1843c742bdd6be1bf0faed7ff3208f), 83 | 4294967295: (0x2e768d4b624578616c2bf1694a975337fb8729c87e08957d284bbc79b401682, 0x4eb4a25a350c7c9a33282c700da2c187efb514fc056b92f6d249db423be1fb3c), 84 | 18446744073709551616: (0x6222bd88bf2df9d5d44b60cfb4a08a960078db7ed51a35eb3e0b6b8ff4eda202, 0x325bb42ea4ed025dd6bdaed261b7c4f5410b608ba902b068f1efa5782e45313), 85 | 2833419889721787128217: (0x2462d10f10d73e1ee34f23e8995c6b335134764e3edb18cd51aa064815da074e, 0x3e8e3dd79f911bfe8f1be627201c60462334431f6bf712615ed27962dd5ec90b), 86 | 309485009821345068724781055: (0x674ad10bbd2df4ce13533bcfd25afebe1d55690377fff91b89f1c1bbf44e6f7, 0x5d78bffab87940cebd0ce34488e0d49d4dd1cc5820ca6780e6af721f6d389c04), 87 | } 88 | } 89 | 90 | def test_generator(self): 91 | for (curvename, points) in self._TEST_POINTS.items(): 92 | curve = getcurvebyname(curvename) 93 | 94 | self.assertEqual(curve.G.x, points[1][0]) 95 | self.assertEqual(curve.G.y, points[1][1]) 96 | 97 | def test_point_doubling(self): 98 | for (curvename, points) in self._TEST_POINTS.items(): 99 | curve = getcurvebyname(curvename) 100 | 101 | P = curve.G + curve.G 102 | self.assertEqual(P.x, points[2][0]) 103 | self.assertEqual(P.y, points[2][1]) 104 | 105 | def test_point_addition(self): 106 | for (curvename, points) in self._TEST_POINTS.items(): 107 | curve = getcurvebyname(curvename) 108 | 109 | P = (curve.G + curve.G) + curve.G 110 | self.assertEqual(P.x, points[3][0]) 111 | self.assertEqual(P.y, points[3][1]) 112 | 113 | def test_scalar_multiplication(self): 114 | for (curvename, points) in self._TEST_POINTS.items(): 115 | curve = getcurvebyname(curvename) 116 | for (scalar, (expectx, expecty)) in points.items(): 117 | Q = curve.G * scalar 118 | P = scalar * curve.G 119 | self.assertEqual(P, Q) 120 | self.assertEqual(P.x, expectx) 121 | self.assertEqual(P.y, expecty) 122 | 123 | def test_negation(self): 124 | for (curvename, points) in self._TEST_POINTS.items(): 125 | curve = getcurvebyname(curvename) 126 | 127 | P = (curve.G + curve.G) 128 | P = P + (-curve.G) 129 | self.assertEqual(P, curve.G) 130 | 131 | def test_neutral(self): 132 | for (curvename, points) in self._TEST_POINTS.items(): 133 | curve = getcurvebyname(curvename) 134 | 135 | P = curve.G 136 | P = P + (-curve.G) 137 | self.assertTrue(P.is_neutral) 138 | 139 | Q = curve.G + curve.G 140 | P = curve.neutral() + Q 141 | self.assertEqual(P, Q) 142 | 143 | -------------------------------------------------------------------------------- /construction-1/ecc/tests/ECTests.py: -------------------------------------------------------------------------------- 1 | # 2 | # joeecc - A small Elliptic Curve Cryptography Demonstration. 3 | # Copyright (C) 2011-2015 Johannes Bauer 4 | # 5 | # This file is part of joeecc. 6 | # 7 | # joeecc is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; this program is ONLY licensed under 10 | # version 3 of the License, later versions are explicitly excluded. 11 | # 12 | # joeecc is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with joeecc; if not, write to the Free Software 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | # 21 | # Johannes Bauer 22 | # 23 | 24 | import unittest 25 | from ..ShortWeierstrassCurve import ShortWeierstrassCurve 26 | from ..AffineCurvePoint import AffineCurvePoint 27 | from .. import getcurvebyname 28 | 29 | class ECTests(unittest.TestCase): 30 | def test_basic1(self): 31 | e = ShortWeierstrassCurve(-3, 5, 23, 0, 0, 13, 22) 32 | x = AffineCurvePoint(21, 16, e) 33 | y = AffineCurvePoint(14, 19, e) 34 | self.assertTrue(x.oncurve()) 35 | self.assertTrue(y.oncurve()) 36 | self.assertTrue((x + y).oncurve()) 37 | self.assertEqual((x + y), AffineCurvePoint(14, 4, e)) 38 | self.assertTrue((x + x).oncurve()) 39 | self.assertEqual((x + x), AffineCurvePoint(5, 0, e)) 40 | self.assertTrue((y + y).oncurve()) 41 | self.assertEqual((y + y), AffineCurvePoint(21, 7, e)) 42 | 43 | def test_basic2(self): 44 | e = ShortWeierstrassCurve(2, 5, 23, 0, 0, 9, 4) 45 | x = AffineCurvePoint(9, 4, e) 46 | y = AffineCurvePoint(10, 6, e) 47 | # (9, 4) + (10, 6) = (8, 21) 48 | # (9, 4) + (9, 4) = (6, 16) 49 | self.assertTrue(x.oncurve()) 50 | self.assertTrue(y.oncurve()) 51 | z = x + y 52 | 53 | self.assertTrue(z.oncurve()) 54 | z = x + x 55 | self.assertTrue(z.oncurve()) 56 | z = y + y 57 | self.assertTrue(z.oncurve()) 58 | 59 | x = AffineCurvePoint(9, 5, e) 60 | self.assertFalse(x.oncurve()) 61 | 62 | def test_basic3(self): 63 | # Testing data from http://christelbach.com/ECCalculator.aspx 64 | e = ShortWeierstrassCurve(3, 99, 101, 0, 0, 12, 34) 65 | self.assertTrue((e.G * 0).is_neutral) 66 | self.assertEqual((e.G * 1), e.G) 67 | self.assertEqual((e.G * 2), AffineCurvePoint(93, 88, e)) 68 | self.assertEqual((e.G * 3), AffineCurvePoint(75, 25, e)) 69 | self.assertEqual((e.G * 4), AffineCurvePoint(47, 72, e)) 70 | self.assertEqual((e.G * 5), AffineCurvePoint(21, 63, e)) 71 | self.assertEqual((e.G * 55), AffineCurvePoint(71, 28, e)) 72 | self.assertEqual((e.G * 123), AffineCurvePoint(91, 33, e)) 73 | self.assertTrue((e.G * 99).is_neutral) 74 | self.assertEqual(e.naive_order_calculation(), 99) 75 | 76 | def test_extd(self): 77 | e = getcurvebyname("secp112r1") 78 | points = [ 79 | AffineCurvePoint(3117110232563059246980187946198621, 3317437604270820210689740076391407, e), 80 | AffineCurvePoint(1337243996230764682967860953280223, 2063522037029258959118399626141682, e), 81 | AffineCurvePoint(235253700287668808185890937034851, 830989660091878453658335933918000, e), 82 | AffineCurvePoint(627781032099779919607023000566247, 1603622602577594429014913566107033, e), 83 | AffineCurvePoint(1929761220615891268483335561783138, 1546624911677232240933310892908962, e), 84 | AffineCurvePoint(872432267721461912738308679449077, 2729640644726851734745963545037841, e), 85 | ] 86 | for point in points: 87 | self.assertTrue(point.oncurve()) 88 | self.assertEqual(points[0] + points[0], AffineCurvePoint(4064734346459959837711463108666078, 1633739364791553181243017790342803, e)) 89 | self.assertTrue(AffineCurvePoint(4064734346459959837711463108666078, 1633739364791553181243017790342803, e).oncurve()) 90 | self.assertEqual(points[0] + points[1], AffineCurvePoint(3723026810340743432839738672226419, 539418558131017701255799570461878, e)) 91 | self.assertTrue(AffineCurvePoint(3723026810340743432839738672226419, 539418558131017701255799570461878, e).oncurve()) 92 | self.assertEqual(points[0] + points[2], AffineCurvePoint(2666739795283455355388717400402993, 2972821526814170767052592315049242, e)) 93 | self.assertTrue(AffineCurvePoint(2666739795283455355388717400402993, 2972821526814170767052592315049242, e).oncurve()) 94 | self.assertEqual(points[0] + points[3], AffineCurvePoint(87040431305643233801949973598186, 4174712248394499122322627644575650, e)) 95 | self.assertTrue(AffineCurvePoint(87040431305643233801949973598186, 4174712248394499122322627644575650, e).oncurve()) 96 | self.assertEqual(points[0] + points[4], AffineCurvePoint(2802418382414800560683276089692115, 2630760185865310406957414586693079, e)) 97 | self.assertTrue(AffineCurvePoint(2802418382414800560683276089692115, 2630760185865310406957414586693079, e).oncurve()) 98 | self.assertEqual(points[0] + points[5], AffineCurvePoint(4288609280448373691375140747355688, 420581842128121271226447977613081, e)) 99 | self.assertTrue(AffineCurvePoint(4288609280448373691375140747355688, 420581842128121271226447977613081, e).oncurve()) 100 | self.assertEqual(points[1] + points[0], AffineCurvePoint(3723026810340743432839738672226419, 539418558131017701255799570461878, e)) 101 | self.assertTrue(AffineCurvePoint(3723026810340743432839738672226419, 539418558131017701255799570461878, e).oncurve()) 102 | self.assertEqual(points[1] + points[1], AffineCurvePoint(3591145884720261338103575780699807, 4315217519961907532019414100448261, e)) 103 | self.assertTrue(AffineCurvePoint(3591145884720261338103575780699807, 4315217519961907532019414100448261, e).oncurve()) 104 | self.assertEqual(points[1] + points[2], AffineCurvePoint(767654518279343783442373102239656, 931581834311445282420568360496919, e)) 105 | self.assertTrue(AffineCurvePoint(767654518279343783442373102239656, 931581834311445282420568360496919, e).oncurve()) 106 | self.assertEqual(points[1] + points[3], AffineCurvePoint(3586051730372413391716540216032874, 1732668913318031500067892336307807, e)) 107 | self.assertTrue(AffineCurvePoint(3586051730372413391716540216032874, 1732668913318031500067892336307807, e).oncurve()) 108 | self.assertEqual(points[1] + points[4], AffineCurvePoint(4319220890821527825482144178575612, 723068585981600829545356089627049, e)) 109 | self.assertTrue(AffineCurvePoint(4319220890821527825482144178575612, 723068585981600829545356089627049, e).oncurve()) 110 | self.assertEqual(points[1] + points[5], AffineCurvePoint(3782803895644916151556214584437161, 2771961082269130926455794722149390, e)) 111 | self.assertTrue(AffineCurvePoint(3782803895644916151556214584437161, 2771961082269130926455794722149390, e).oncurve()) 112 | self.assertEqual(points[2] + points[0], AffineCurvePoint(2666739795283455355388717400402993, 2972821526814170767052592315049242, e)) 113 | self.assertTrue(AffineCurvePoint(2666739795283455355388717400402993, 2972821526814170767052592315049242, e).oncurve()) 114 | self.assertEqual(points[2] + points[1], AffineCurvePoint(767654518279343783442373102239656, 931581834311445282420568360496919, e)) 115 | self.assertTrue(AffineCurvePoint(767654518279343783442373102239656, 931581834311445282420568360496919, e).oncurve()) 116 | self.assertEqual(points[2] + points[2], AffineCurvePoint(2120325548453476461903987486245115, 2843555047937458025861854944861757, e)) 117 | self.assertTrue(AffineCurvePoint(2120325548453476461903987486245115, 2843555047937458025861854944861757, e).oncurve()) 118 | self.assertEqual(points[2] + points[3], AffineCurvePoint(2869160181194689537159393771033225, 2388609795801451355008363813919312, e)) 119 | self.assertTrue(AffineCurvePoint(2869160181194689537159393771033225, 2388609795801451355008363813919312, e).oncurve()) 120 | self.assertEqual(points[2] + points[4], AffineCurvePoint(1443848317651251533912280184260615, 3507966784103250297258176930645556, e)) 121 | self.assertTrue(AffineCurvePoint(1443848317651251533912280184260615, 3507966784103250297258176930645556, e).oncurve()) 122 | self.assertEqual(points[2] + points[5], AffineCurvePoint(1528876984675717023713801774301100, 3700884665652262932134185881457463, e)) 123 | self.assertTrue(AffineCurvePoint(1528876984675717023713801774301100, 3700884665652262932134185881457463, e).oncurve()) 124 | self.assertEqual(points[3] + points[0], AffineCurvePoint(87040431305643233801949973598186, 4174712248394499122322627644575650, e)) 125 | self.assertTrue(AffineCurvePoint(87040431305643233801949973598186, 4174712248394499122322627644575650, e).oncurve()) 126 | self.assertEqual(points[3] + points[1], AffineCurvePoint(3586051730372413391716540216032874, 1732668913318031500067892336307807, e)) 127 | self.assertTrue(AffineCurvePoint(3586051730372413391716540216032874, 1732668913318031500067892336307807, e).oncurve()) 128 | self.assertEqual(points[3] + points[2], AffineCurvePoint(2869160181194689537159393771033225, 2388609795801451355008363813919312, e)) 129 | self.assertTrue(AffineCurvePoint(2869160181194689537159393771033225, 2388609795801451355008363813919312, e).oncurve()) 130 | self.assertEqual(points[3] + points[3], AffineCurvePoint(176878457604457698579663631864190, 721471289065271224834385424962611, e)) 131 | self.assertTrue(AffineCurvePoint(176878457604457698579663631864190, 721471289065271224834385424962611, e).oncurve()) 132 | self.assertEqual(points[3] + points[4], AffineCurvePoint(2562156057939871711326640460445945, 3577511574269877768475169588752653, e)) 133 | self.assertTrue(AffineCurvePoint(2562156057939871711326640460445945, 3577511574269877768475169588752653, e).oncurve()) 134 | self.assertEqual(points[3] + points[5], AffineCurvePoint(148146258284214251215275786030378, 1329592514181691255155018041558553, e)) 135 | self.assertTrue(AffineCurvePoint(148146258284214251215275786030378, 1329592514181691255155018041558553, e).oncurve()) 136 | self.assertEqual(points[4] + points[0], AffineCurvePoint(2802418382414800560683276089692115, 2630760185865310406957414586693079, e)) 137 | self.assertTrue(AffineCurvePoint(2802418382414800560683276089692115, 2630760185865310406957414586693079, e).oncurve()) 138 | self.assertEqual(points[4] + points[1], AffineCurvePoint(4319220890821527825482144178575612, 723068585981600829545356089627049, e)) 139 | self.assertTrue(AffineCurvePoint(4319220890821527825482144178575612, 723068585981600829545356089627049, e).oncurve()) 140 | self.assertEqual(points[4] + points[2], AffineCurvePoint(1443848317651251533912280184260615, 3507966784103250297258176930645556, e)) 141 | self.assertTrue(AffineCurvePoint(1443848317651251533912280184260615, 3507966784103250297258176930645556, e).oncurve()) 142 | self.assertEqual(points[4] + points[3], AffineCurvePoint(2562156057939871711326640460445945, 3577511574269877768475169588752653, e)) 143 | self.assertTrue(AffineCurvePoint(2562156057939871711326640460445945, 3577511574269877768475169588752653, e).oncurve()) 144 | self.assertEqual(points[4] + points[4], AffineCurvePoint(3074072036822685021436989941342785, 3157984599511588306440992673720004, e)) 145 | self.assertTrue(AffineCurvePoint(3074072036822685021436989941342785, 3157984599511588306440992673720004, e).oncurve()) 146 | self.assertEqual(points[4] + points[5], AffineCurvePoint(2219827979145724699972786737693217, 4167759417703712591322494207750534, e)) 147 | self.assertTrue(AffineCurvePoint(2219827979145724699972786737693217, 4167759417703712591322494207750534, e).oncurve()) 148 | self.assertEqual(points[5] + points[0], AffineCurvePoint(4288609280448373691375140747355688, 420581842128121271226447977613081, e)) 149 | self.assertTrue(AffineCurvePoint(4288609280448373691375140747355688, 420581842128121271226447977613081, e).oncurve()) 150 | self.assertEqual(points[5] + points[1], AffineCurvePoint(3782803895644916151556214584437161, 2771961082269130926455794722149390, e)) 151 | self.assertTrue(AffineCurvePoint(3782803895644916151556214584437161, 2771961082269130926455794722149390, e).oncurve()) 152 | self.assertEqual(points[5] + points[2], AffineCurvePoint(1528876984675717023713801774301100, 3700884665652262932134185881457463, e)) 153 | self.assertTrue(AffineCurvePoint(1528876984675717023713801774301100, 3700884665652262932134185881457463, e).oncurve()) 154 | self.assertEqual(points[5] + points[3], AffineCurvePoint(148146258284214251215275786030378, 1329592514181691255155018041558553, e)) 155 | self.assertTrue(AffineCurvePoint(148146258284214251215275786030378, 1329592514181691255155018041558553, e).oncurve()) 156 | self.assertEqual(points[5] + points[4], AffineCurvePoint(2219827979145724699972786737693217, 4167759417703712591322494207750534, e)) 157 | self.assertTrue(AffineCurvePoint(2219827979145724699972786737693217, 4167759417703712591322494207750534, e).oncurve()) 158 | self.assertEqual(points[5] + points[5], AffineCurvePoint(137680862920165800159415222573783, 3475375738534728619472562866721341, e)) 159 | self.assertTrue(AffineCurvePoint(137680862920165800159415222573783, 3475375738534728619472562866721341, e).oncurve()) 160 | self.assertEqual(244731188 * points[0], AffineCurvePoint(799343867892131331328116631700028, 3238045619580805561449053238064641, e)) 161 | self.assertTrue(AffineCurvePoint(799343867892131331328116631700028, 3238045619580805561449053238064641, e).oncurve()) 162 | self.assertEqual(479215585 * points[0], AffineCurvePoint(2706730081538110138078384782047852, 2881713554078961053511508101371441, e)) 163 | self.assertTrue(AffineCurvePoint(2706730081538110138078384782047852, 2881713554078961053511508101371441, e).oncurve()) 164 | self.assertEqual(615977890 * points[0], AffineCurvePoint(3838979374142936020593894026971284, 2353562327773064373435074287667816, e)) 165 | self.assertTrue(AffineCurvePoint(3838979374142936020593894026971284, 2353562327773064373435074287667816, e).oncurve()) 166 | self.assertEqual(550140093 * points[0], AffineCurvePoint(200065277622376526049681520014276, 51209742086984118724200802806153, e)) 167 | self.assertTrue(AffineCurvePoint(200065277622376526049681520014276, 51209742086984118724200802806153, e).oncurve()) 168 | self.assertEqual(540588643 * points[0], AffineCurvePoint(2708454351094974414186353284132004, 482908022980745877814430356771611, e)) 169 | self.assertTrue(AffineCurvePoint(2708454351094974414186353284132004, 482908022980745877814430356771611, e).oncurve()) 170 | self.assertEqual(672739461 * points[0], AffineCurvePoint(1030814758650133152061550844236032, 1823080711222015183880343693623151, e)) 171 | self.assertTrue(AffineCurvePoint(1030814758650133152061550844236032, 1823080711222015183880343693623151, e).oncurve()) 172 | self.assertEqual(910647265 * points[1], AffineCurvePoint(137737857707196532599472608676360, 957907527391095020531740031338079, e)) 173 | self.assertTrue(AffineCurvePoint(137737857707196532599472608676360, 957907527391095020531740031338079, e).oncurve()) 174 | self.assertEqual(399781155 * points[1], AffineCurvePoint(3761977973845283625480428585967217, 2353350788128670145920555879879491, e)) 175 | self.assertTrue(AffineCurvePoint(3761977973845283625480428585967217, 2353350788128670145920555879879491, e).oncurve()) 176 | self.assertEqual(438499287 * points[1], AffineCurvePoint(791784310872674310944665210228985, 1430904795413769943854621265242346, e)) 177 | self.assertTrue(AffineCurvePoint(791784310872674310944665210228985, 1430904795413769943854621265242346, e).oncurve()) 178 | self.assertEqual(30329342 * points[1], AffineCurvePoint(842488465058721644608558481954980, 3887929284060323035133050694924699, e)) 179 | self.assertTrue(AffineCurvePoint(842488465058721644608558481954980, 3887929284060323035133050694924699, e).oncurve()) 180 | self.assertEqual(967116404 * points[1], AffineCurvePoint(4155601987656967768431349496277491, 192440768853698673613506368932279, e)) 181 | self.assertTrue(AffineCurvePoint(4155601987656967768431349496277491, 192440768853698673613506368932279, e).oncurve()) 182 | self.assertEqual(927133616 * points[1], AffineCurvePoint(2556810828429079101914439119665354, 2524847108175393854549561825759512, e)) 183 | self.assertTrue(AffineCurvePoint(2556810828429079101914439119665354, 2524847108175393854549561825759512, e).oncurve()) 184 | self.assertEqual(206990082 * points[2], AffineCurvePoint(1707574986822913143399470421926442, 131328589915508399663105547392277, e)) 185 | self.assertTrue(AffineCurvePoint(1707574986822913143399470421926442, 131328589915508399663105547392277, e).oncurve()) 186 | self.assertEqual(145434778 * points[2], AffineCurvePoint(193470908356734603666578767473410, 3004503290193422403586016715967043, e)) 187 | self.assertTrue(AffineCurvePoint(193470908356734603666578767473410, 3004503290193422403586016715967043, e).oncurve()) 188 | self.assertEqual(454728583 * points[2], AffineCurvePoint(4400079036925892699736681855331890, 3088617866065122674311000109236495, e)) 189 | self.assertTrue(AffineCurvePoint(4400079036925892699736681855331890, 3088617866065122674311000109236495, e).oncurve()) 190 | self.assertEqual(135155369 * points[2], AffineCurvePoint(2027712979252276636045660473448539, 2164103391295458545875249924786406, e)) 191 | self.assertTrue(AffineCurvePoint(2027712979252276636045660473448539, 2164103391295458545875249924786406, e).oncurve()) 192 | self.assertEqual(3646348 * points[2], AffineCurvePoint(222482181719241110158914176464073, 1175253763932995577527931926137281, e)) 193 | self.assertTrue(AffineCurvePoint(222482181719241110158914176464073, 1175253763932995577527931926137281, e).oncurve()) 194 | self.assertEqual(510578945 * points[2], AffineCurvePoint(1261291574979275348201458226343995, 3102733652715577691117533666551442, e)) 195 | self.assertTrue(AffineCurvePoint(1261291574979275348201458226343995, 3102733652715577691117533666551442, e).oncurve()) 196 | self.assertEqual(773473903 * points[3], AffineCurvePoint(741959927009188871583680615949638, 2093971120945716035639075368016278, e)) 197 | self.assertTrue(AffineCurvePoint(741959927009188871583680615949638, 2093971120945716035639075368016278, e).oncurve()) 198 | self.assertEqual(997111420 * points[3], AffineCurvePoint(1248100720882585714838579280838399, 4438594924170079853980619795252553, e)) 199 | self.assertTrue(AffineCurvePoint(1248100720882585714838579280838399, 4438594924170079853980619795252553, e).oncurve()) 200 | self.assertEqual(668321744 * points[3], AffineCurvePoint(395886649333065339235666595510340, 3755881760237441545879003514708540, e)) 201 | self.assertTrue(AffineCurvePoint(395886649333065339235666595510340, 3755881760237441545879003514708540, e).oncurve()) 202 | self.assertEqual(829980073 * points[3], AffineCurvePoint(1735323911926967505958820072450473, 1405878229247618255874049365208656, e)) 203 | self.assertTrue(AffineCurvePoint(1735323911926967505958820072450473, 1405878229247618255874049365208656, e).oncurve()) 204 | self.assertEqual(441912688 * points[3], AffineCurvePoint(2904753317362970167836831382358365, 1137554067721498868296881430795660, e)) 205 | self.assertTrue(AffineCurvePoint(2904753317362970167836831382358365, 1137554067721498868296881430795660, e).oncurve()) 206 | self.assertEqual(970575074 * points[3], AffineCurvePoint(313100336875746517104210806321395, 2084520610118571098315493974262361, e)) 207 | self.assertTrue(AffineCurvePoint(313100336875746517104210806321395, 2084520610118571098315493974262361, e).oncurve()) 208 | self.assertEqual(606215582 * points[4], AffineCurvePoint(2850264680963666931636271668878004, 2167820720348711946721651674088979, e)) 209 | self.assertTrue(AffineCurvePoint(2850264680963666931636271668878004, 2167820720348711946721651674088979, e).oncurve()) 210 | self.assertEqual(968223364 * points[4], AffineCurvePoint(752966669767470049793829658672502, 817295934273335397573319216079235, e)) 211 | self.assertTrue(AffineCurvePoint(752966669767470049793829658672502, 817295934273335397573319216079235, e).oncurve()) 212 | self.assertEqual(26106169 * points[4], AffineCurvePoint(404431198475874236899098181363662, 2296789183245184747073488685011926, e)) 213 | self.assertTrue(AffineCurvePoint(404431198475874236899098181363662, 2296789183245184747073488685011926, e).oncurve()) 214 | self.assertEqual(379289443 * points[4], AffineCurvePoint(723353446510304113034686043795598, 292865962596212029663654924152756, e)) 215 | self.assertTrue(AffineCurvePoint(723353446510304113034686043795598, 292865962596212029663654924152756, e).oncurve()) 216 | self.assertEqual(523987778 * points[4], AffineCurvePoint(825694777938573065404675043994059, 1338729390845431942346396395449572, e)) 217 | self.assertTrue(AffineCurvePoint(825694777938573065404675043994059, 1338729390845431942346396395449572, e).oncurve()) 218 | self.assertEqual(885647483 * points[4], AffineCurvePoint(801298464780419945624371970788438, 4072001729606023524262744717618362, e)) 219 | self.assertTrue(AffineCurvePoint(801298464780419945624371970788438, 4072001729606023524262744717618362, e).oncurve()) 220 | self.assertEqual(634165049 * points[5], AffineCurvePoint(314787966440069146423812028140757, 3759178934144635742129828380139388, e)) 221 | self.assertTrue(AffineCurvePoint(314787966440069146423812028140757, 3759178934144635742129828380139388, e).oncurve()) 222 | self.assertEqual(406547467 * points[5], AffineCurvePoint(3915579942088610581276212551825744, 1735075139758492739634365954880527, e)) 223 | self.assertTrue(AffineCurvePoint(3915579942088610581276212551825744, 1735075139758492739634365954880527, e).oncurve()) 224 | self.assertEqual(977999735 * points[5], AffineCurvePoint(4047764598782335211666165260642656, 3390395305328029707188373076630799, e)) 225 | self.assertTrue(AffineCurvePoint(4047764598782335211666165260642656, 3390395305328029707188373076630799, e).oncurve()) 226 | self.assertEqual(59143884 * points[5], AffineCurvePoint(4142931471858723228703092484057487, 1211817578182076750442156342501316, e)) 227 | self.assertTrue(AffineCurvePoint(4142931471858723228703092484057487, 1211817578182076750442156342501316, e).oncurve()) 228 | self.assertEqual(130367752 * points[5], AffineCurvePoint(2080598045063511954398353433475040, 3372609893215355160406007246405785, e)) 229 | self.assertTrue(AffineCurvePoint(2080598045063511954398353433475040, 3372609893215355160406007246405785, e).oncurve()) 230 | self.assertEqual(537668229 * points[5], AffineCurvePoint(2137496744785763901399697229984622, 4394820220824082213468385758117630, e)) 231 | self.assertTrue(AffineCurvePoint(2137496744785763901399697229984622, 4394820220824082213468385758117630, e).oncurve()) 232 | 233 | -------------------------------------------------------------------------------- /construction-1/ecc/tests/Ed25519BasicTests.py: -------------------------------------------------------------------------------- 1 | # 2 | # joeecc - A small Elliptic Curve Cryptography Demonstration. 3 | # Copyright (C) 2011-2015 Johannes Bauer 4 | # 5 | # This file is part of joeecc. 6 | # 7 | # joeecc is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; this program is ONLY licensed under 10 | # version 3 of the License, later versions are explicitly excluded. 11 | # 12 | # joeecc is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with joeecc; if not, write to the Free Software 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | # 21 | # Johannes Bauer 22 | # 23 | 24 | import unittest 25 | from .. import FieldElement, getcurvebyname, ECPublicKey, ECPrivateKey 26 | 27 | class Ed25519BasicTests(unittest.TestCase): 28 | def test_sign_verify(self): 29 | curve = getcurvebyname("ed25519") 30 | privkey = ECPrivateKey.eddsa_generate(curve) 31 | 32 | msg = b"foobar" 33 | signature = privkey.eddsa_sign(msg) 34 | 35 | self.assertTrue(privkey.pubkey.eddsa_verify(msg, signature)) 36 | self.assertFalse(privkey.pubkey.eddsa_verify(msg + b"x", signature)) 37 | 38 | def test_sig_encode_decode(self): 39 | curve = getcurvebyname("ed25519") 40 | privkey = ECPrivateKey.eddsa_generate(curve) 41 | msg = b"foobar" 42 | signature = privkey.eddsa_sign(msg) 43 | 44 | encoded_signature = signature.encode() 45 | decoded_signature = ECPrivateKey.EDDSASignature.decode(curve, encoded_signature) 46 | self.assertEqual(decoded_signature, signature) 47 | self.assertTrue(privkey.pubkey.eddsa_verify(msg, signature)) 48 | self.assertTrue(privkey.pubkey.eddsa_verify(msg, decoded_signature)) 49 | 50 | def test_seeding_signing(self): 51 | curve = getcurvebyname("ed25519") 52 | seed = bytes.fromhex("5da0ed08799092411e90140e7b86058276fe293efd40afa816bc0ccc3f43492e") 53 | 54 | privkey = ECPrivateKey.eddsa_generate(curve, seed = seed) 55 | self.assertEqual(privkey.seed, seed) 56 | self.assertEqual(privkey.scalar, 55506792121812326601863127824214732996787216741471646079326674346494898512112) 57 | 58 | pubkey = privkey.pubkey 59 | self.assertEqual(pubkey.point.x, 0x7de7bc3e0b0c077c2a104623a8e66cb7d9ffb3b1a594969bb55997dbe66d4264) 60 | self.assertEqual(pubkey.point.y, 0x704f7339f697f88d190052a76091805f24c77aa232acf69b19082fa036967744) 61 | 62 | msg = b"Foobar!" 63 | signature = privkey.eddsa_sign(msg) 64 | 65 | self.assertEqual(signature.R.x, 0x7fc3a9aca15bb635bc471c6fd410f12e3658e0b226452f025992c931ab61fc18) 66 | self.assertEqual(signature.R.y, 0x3a5902651bf0eb71dfbb604d3e20511821f7e720b5814e8a9b744aede20e7986) 67 | self.assertEqual(signature.s, 1517157819819635474038904401642496669072502937558957834094270557835510822428) 68 | 69 | 70 | def test_key_encoding(self): 71 | curve = getcurvebyname("ed25519") 72 | seed = bytes.fromhex("5da0ed08799092411e90140e7b86058276fe293efd40afa816bc0ccc3f43492e") 73 | 74 | privkey = ECPrivateKey.eddsa_generate(curve, seed = seed) 75 | 76 | self.assertEqual(privkey.eddsa_encode(), bytes.fromhex("5da0ed08799092411e90140e7b86058276fe293efd40afa816bc0ccc3f43492e")) 77 | self.assertEqual(privkey.pubkey.eddsa_encode(), bytes.fromhex("44779636a02f08199bf6ac32a27ac7245f809160a75200198df897f639734f70")) 78 | 79 | def test_key_decoding(self): 80 | curve = getcurvebyname("ed25519") 81 | seed = bytes.fromhex("5da0ed08799092411e90140e7b86058276fe293efd40afa816bc0ccc3f43492e") 82 | 83 | privkey = ECPrivateKey.eddsa_decode(curve, bytes.fromhex("5da0ed08799092411e90140e7b86058276fe293efd40afa816bc0ccc3f43492e")) 84 | self.assertEqual(privkey.seed, seed) 85 | self.assertEqual(privkey.scalar, 55506792121812326601863127824214732996787216741471646079326674346494898512112) 86 | 87 | pubkey = ECPublicKey.eddsa_decode(curve, bytes.fromhex("44779636a02f08199bf6ac32a27ac7245f809160a75200198df897f639734f70")) 88 | self.assertEqual(pubkey.point, privkey.pubkey.point) 89 | 90 | 91 | def test_sig_encoding(self): 92 | curve = getcurvebyname("ed25519") 93 | seed = bytes.fromhex("5da0ed08799092411e90140e7b86058276fe293efd40afa816bc0ccc3f43492e") 94 | 95 | privkey = ECPrivateKey.eddsa_generate(curve, seed = seed) 96 | 97 | msg = b"Foobar!" 98 | signature = privkey.eddsa_sign(msg) 99 | 100 | self.assertEqual(signature.encode(), bytes.fromhex("86790ee2ed4a749b8a4e81b520e7f7211851203e4d60bbdf71ebf01b6502593a1c36ca859621a386dfaa79c5a24bb6eef1111c76bfb7fc0c48491b2b4fae5a03")) 101 | 102 | def test_sig_decoding(self): 103 | curve = getcurvebyname("ed25519") 104 | encoded_sig = bytes.fromhex("86790ee2ed4a749b8a4e81b520e7f7211851203e4d60bbdf71ebf01b6502593a1c36ca859621a386dfaa79c5a24bb6eef1111c76bfb7fc0c48491b2b4fae5a03") 105 | 106 | signature = ECPrivateKey.EDDSASignature.decode(curve, encoded_sig) 107 | self.assertEqual(signature.R.x, 0x7fc3a9aca15bb635bc471c6fd410f12e3658e0b226452f025992c931ab61fc18) 108 | self.assertEqual(signature.R.y, 0x3a5902651bf0eb71dfbb604d3e20511821f7e720b5814e8a9b744aede20e7986) 109 | self.assertEqual(signature.s, 1517157819819635474038904401642496669072502937558957834094270557835510822428) 110 | -------------------------------------------------------------------------------- /construction-1/ecc/tests/Ed25519ExtdTests.py: -------------------------------------------------------------------------------- 1 | # 2 | # joeecc - A small Elliptic Curve Cryptography Demonstration. 3 | # Copyright (C) 2011-2015 Johannes Bauer 4 | # 5 | # This file is part of joeecc. 6 | # 7 | # joeecc is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; this program is ONLY licensed under 10 | # version 3 of the License, later versions are explicitly excluded. 11 | # 12 | # joeecc is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with joeecc; if not, write to the Free Software 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | # 21 | # Johannes Bauer 22 | # 23 | 24 | import unittest 25 | import random 26 | from .. import FieldElement, getcurvebyname, ECPrivateKey, ECPublicKey, AffineCurvePoint 27 | 28 | class Testcase(object): 29 | def __init__(self, name, params): 30 | self._name = name 31 | self._params = params 32 | 33 | @property 34 | def name(self): 35 | return self._name 36 | 37 | @staticmethod 38 | def parse_Bytes(value): 39 | return bytes.fromhex(value) 40 | 41 | @staticmethod 42 | def parse_Int(value): 43 | return int(value) 44 | 45 | def dump(self): 46 | for key in sorted(list(self._params.keys())): 47 | value = self._params[key] 48 | if isinstance(value, bytes): 49 | value = "(%d) " % (len(value)) + "".join("%02x" % (c) for c in value) 50 | else: 51 | value = str(value) 52 | print("%-20s: %s" % (key, value)) 53 | 54 | def __getitem__(self, key): 55 | return self._params[key] 56 | 57 | def __str__(self): 58 | return "Testcase<%s [%s]>" % (self.name, ", ".join(sorted(list(self._params.keys())))) 59 | 60 | def tcs_from_file(filename): 61 | f = open(filename, "r") 62 | for line in f: 63 | line = line.rstrip("\r\n") 64 | line = line.split("|") 65 | 66 | tcname = line[0] 67 | prototypes = [ arg.split(":") for arg in line[1].split(",") ] 68 | values = line[2:] 69 | 70 | assert(len(prototypes) == len(values)) 71 | parsed_values = { } 72 | for ((vartype, varname), value) in zip(prototypes, values): 73 | parser = getattr(Testcase, "parse_" + vartype) 74 | value = parser(value) 75 | parsed_values[varname] = value 76 | yield Testcase(tcname, parsed_values) 77 | f.close() 78 | 79 | class Ed25519ExtdTests(unittest.TestCase): 80 | _TEST_SCOPE = "minimal" 81 | 82 | @classmethod 83 | def set_test_scope(cls, scope): 84 | cls._TEST_SCOPE = scope 85 | 86 | def setUp(self): 87 | self._basedir = "testdata/curve25519/" 88 | self._curve = getcurvebyname("ed25519") 89 | 90 | def _run_EncodePoint(self, tc): 91 | point = AffineCurvePoint(tc["X"], tc["Y"], self._curve) 92 | encoded = point.eddsa_encode() 93 | self.assertTrue(isinstance(encoded, bytes)) 94 | self.assertTrue(len(encoded) == 32) 95 | self.assertEqual(encoded, tc["EncodedPoint"]) 96 | self.assertEqual(AffineCurvePoint.eddsa_decode(self._curve, tc["EncodedPoint"]), point) 97 | 98 | def _run_SignData(self, tc): 99 | pubkey = AffineCurvePoint.eddsa_decode(self._curve, tc["EncodedPubKey"]) 100 | keypair = ECPrivateKey.eddsa_decode(self._curve, tc["EncodedPrivKey"]) 101 | self.assertEqual(keypair.pubkey.point, pubkey) 102 | signature = keypair.eddsa_sign(tc["Message"]) 103 | self.assertEqual(signature.encode(), tc["Signature"]) 104 | self.assertTrue(keypair.pubkey.eddsa_verify(tc["Message"], signature)) 105 | self.assertFalse(keypair.pubkey.eddsa_verify(tc["Message"] + b"x", signature)) 106 | 107 | def test_encodepoint(self): 108 | for testcase in tcs_from_file(self._basedir + "encodepoint.txt"): 109 | handlername = "_run_" + testcase.name 110 | handler = getattr(self, handlername) 111 | handler(testcase) 112 | 113 | def test_djb_sigs(self): 114 | for testcase in tcs_from_file(self._basedir + "djb.txt"): 115 | # Skip lots of tests randomly for time reasons 116 | if (self._TEST_SCOPE == "minimal") and (random.randrange(100) > 0): 117 | continue 118 | 119 | handlername = "_run_" + testcase.name 120 | handler = getattr(self, handlername) 121 | handler(testcase) 122 | 123 | -------------------------------------------------------------------------------- /construction-1/ecc/tests/FieldElementSqrtTests.py: -------------------------------------------------------------------------------- 1 | # 2 | # joeecc - A small Elliptic Curve Cryptography Demonstration. 3 | # Copyright (C) 2011-2015 Johannes Bauer 4 | # 5 | # This file is part of joeecc. 6 | # 7 | # joeecc is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; this program is ONLY licensed under 10 | # version 3 of the License, later versions are explicitly excluded. 11 | # 12 | # joeecc is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with joeecc; if not, write to the Free Software 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | # 21 | # Johannes Bauer 22 | # 23 | 24 | import unittest 25 | import random 26 | from ..FieldElement import FieldElement 27 | 28 | class FieldElementSqrtTests(unittest.TestCase): 29 | _PRIME_1_MOD_4 = [ 30 | 10153776240248910961, 31 | 13313520292754238121, 32 | 15378050022937467689, 33 | 15438372505554348001, 34 | 15476752070461085857, 35 | 17875746998751974477, 36 | 18057875082506157121, 37 | ] 38 | 39 | _PRIME_3_MOD_4 = [ 40 | 10164036603611688719, 41 | 11802848526449265743, 42 | 12398748969631217971, 43 | 12821403563901948251, 44 | 12871176861409354567, 45 | 13022588269702988959, 46 | 13784119435837260871, 47 | ] 48 | 49 | def test_integrity(self): 50 | for p in self._PRIME_3_MOD_4: 51 | self.assertEqual(p % 4, 3) 52 | 53 | def _test_primes(self, primeset, testcnt = 30): 54 | for p in primeset: 55 | rootable = False 56 | for i in range(testcnt): 57 | qsqr = FieldElement(random.randrange(p), p) 58 | q = qsqr.sqrt() 59 | if q is not None: 60 | rootable = True 61 | (a, b) = q 62 | self.assertEqual(a * a, qsqr) 63 | self.assertEqual(b * b, qsqr) 64 | self.assertTrue(rootable) 65 | 66 | def test_basic(self): 67 | self._test_primes(self._PRIME_3_MOD_4) 68 | 69 | def test_extd(self): 70 | self._test_primes(self._PRIME_1_MOD_4) 71 | 72 | def test_small_body(self): 73 | p = 263 74 | for i in range(1, p): 75 | i = FieldElement(i, p) 76 | q = i.sqr() 77 | r = q.sqrt() 78 | self.assertEqual(r[0] * r[0], q) 79 | self.assertEqual(r[1] * r[1], q) 80 | 81 | -------------------------------------------------------------------------------- /construction-1/ecc/tests/FieldElementTests.py: -------------------------------------------------------------------------------- 1 | # 2 | # joeecc - A small Elliptic Curve Cryptography Demonstration. 3 | # Copyright (C) 2011-2015 Johannes Bauer 4 | # 5 | # This file is part of joeecc. 6 | # 7 | # joeecc is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; this program is ONLY licensed under 10 | # version 3 of the License, later versions are explicitly excluded. 11 | # 12 | # joeecc is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with joeecc; if not, write to the Free Software 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | # 21 | # Johannes Bauer 22 | # 23 | 24 | import unittest 25 | from ..FieldElement import FieldElement 26 | 27 | class FieldElementTests(unittest.TestCase): 28 | def test_basic(self): 29 | a = FieldElement(15, 23) 30 | b = FieldElement(20, 23) 31 | self.assertEqual(a + b, FieldElement(12, 23)) 32 | self.assertEqual(b + a, FieldElement(12, 23)) 33 | self.assertEqual(a + b - b, a) 34 | self.assertEqual(b + a - a, b) 35 | 36 | self.assertEqual(a - b, FieldElement(18, 23)) 37 | self.assertEqual(a - b + b, a) 38 | self.assertEqual(b - a + a, b) 39 | 40 | self.assertEqual(a * b, FieldElement(1, 23)) 41 | self.assertEqual(b * a, FieldElement(1, 23)) 42 | self.assertEqual(a * b // b, a) 43 | self.assertEqual(b * a // a, b) 44 | 45 | self.assertEqual(a // b, FieldElement(18, 23)) 46 | self.assertEqual(a // b * b, a) 47 | self.assertEqual(b // a * a, b) 48 | 49 | self.assertEqual(int(FieldElement(2, 101) ** 473289743783748378), 21) 50 | self.assertEqual(int(FieldElement(3, 101) ** 473289743783748378), 33) 51 | self.assertEqual(int(FieldElement(4, 101) ** 473289743783748378), 37) 52 | self.assertEqual(int(FieldElement(5, 101) ** 473289743783748378), 24) 53 | 54 | x = FieldElement(1000, 2003) 55 | s = x.sqrt() 56 | assert(s) 57 | (s1, s2) = s 58 | self.assertEqual(s1 * s1, x) 59 | self.assertEqual(s2 * s2, x) 60 | 61 | def test_exp(self): 62 | self.assertEqual(int(FieldElement(19, 23) ** 5), 11) 63 | self.assertEqual(int(FieldElement(19, 23) ** 12), 4) 64 | self.assertEqual(int(FieldElement(14, 23) ** 20), 2) 65 | self.assertEqual(int(FieldElement(1, 23) ** 19), 1) 66 | self.assertEqual(int(FieldElement(18, 23) ** 17), 8) 67 | self.assertEqual(int(FieldElement(18, 23) ** 20), 12) 68 | self.assertEqual(int(FieldElement(18, 23) ** 17), 8) 69 | self.assertEqual(int(FieldElement(20, 23) ** 12), 3) 70 | self.assertEqual(int(FieldElement(3, 23) ** 17), 16) 71 | self.assertEqual(int(FieldElement(14, 23) ** 3), 7) 72 | self.assertEqual(int(FieldElement(4, 23) ** 4), 3) 73 | self.assertEqual(int(FieldElement(10, 23) ** 4), 18) 74 | self.assertEqual(int(FieldElement(18, 23) ** 2), 2) 75 | self.assertEqual(int(FieldElement(10, 23) ** 17), 17) 76 | self.assertEqual(int(FieldElement(3, 23) ** 9), 18) 77 | self.assertEqual(int(FieldElement(6, 23) ** 10), 4) 78 | self.assertEqual(int(FieldElement(22, 23) + 3), 2) 79 | self.assertEqual(int(FieldElement(16, 23) + 16), 9) 80 | self.assertEqual(int(FieldElement(22, 23) + 10), 9) 81 | self.assertEqual(int(FieldElement(6, 23) + 22), 5) 82 | self.assertEqual(int(FieldElement(6, 23) + 13), 19) 83 | self.assertEqual(int(FieldElement(20, 23) + 17), 14) 84 | self.assertEqual(int(FieldElement(3, 23) + 2), 5) 85 | self.assertEqual(int(FieldElement(6, 23) + 21), 4) 86 | self.assertEqual(int(FieldElement(16, 23) + 6), 22) 87 | self.assertEqual(int(FieldElement(5, 23) + 6), 11) 88 | self.assertEqual(int(FieldElement(9, 23) + 10), 19) 89 | self.assertEqual(int(FieldElement(18, 23) + 17), 12) 90 | self.assertEqual(int(FieldElement(2, 23) + 15), 17) 91 | self.assertEqual(int(FieldElement(14, 23) + 21), 12) 92 | self.assertEqual(int(FieldElement(15, 23) + 2), 17) 93 | self.assertEqual(int(FieldElement(20, 23) + 20), 17) 94 | self.assertEqual(int(FieldElement(1, 23) - 3), 21) 95 | self.assertEqual(int(FieldElement(12, 23) - 9), 3) 96 | self.assertEqual(int(FieldElement(19, 23) - 3), 16) 97 | self.assertEqual(int(FieldElement(8, 23) - 10), 21) 98 | self.assertEqual(int(FieldElement(4, 23) - 9), 18) 99 | self.assertEqual(int(FieldElement(21, 23) - 20), 1) 100 | self.assertEqual(int(FieldElement(17, 23) - 17), 0) 101 | self.assertEqual(int(FieldElement(8, 23) - 17), 14) 102 | self.assertEqual(int(FieldElement(18, 23) - 9), 9) 103 | self.assertEqual(int(FieldElement(15, 23) - 18), 20) 104 | self.assertEqual(int(FieldElement(7, 23) - 5), 2) 105 | self.assertEqual(int(FieldElement(14, 23) - 21), 16) 106 | self.assertEqual(int(FieldElement(1, 23) - 5), 19) 107 | self.assertEqual(int(FieldElement(13, 23) - 3), 10) 108 | self.assertEqual(int(FieldElement(2, 23) - 1), 1) 109 | self.assertEqual(int(FieldElement(13, 23) - 15), 21) 110 | self.assertEqual(int(FieldElement(13, 23) // 16), 8) 111 | self.assertEqual(int(FieldElement(14, 23) // 8), 19) 112 | self.assertEqual(int(FieldElement(2, 23) // 17), 15) 113 | self.assertEqual(int(FieldElement(0, 23) // 5), 0) 114 | self.assertEqual(int(FieldElement(9, 23) // 6), 13) 115 | self.assertEqual(int(FieldElement(14, 23) // 17), 13) 116 | self.assertEqual(int(FieldElement(1, 23) // 11), 21) 117 | self.assertEqual(int(FieldElement(14, 23) // 9), 22) 118 | self.assertEqual(int(FieldElement(9, 23) // 16), 2) 119 | self.assertEqual(int(FieldElement(1, 23) // 12), 2) 120 | self.assertEqual(int(FieldElement(13, 23) // 21), 5) 121 | self.assertEqual(int(FieldElement(15, 23) // 19), 2) 122 | self.assertEqual(int(FieldElement(5, 23) // 5), 1) 123 | self.assertEqual(int(FieldElement(8, 23) // 6), 9) 124 | self.assertEqual(int(FieldElement(19, 23) // 8), 11) 125 | self.assertEqual(int(FieldElement(4, 23) // 10), 5) 126 | self.assertEqual(int(FieldElement(3, 101) ** 46), 96) 127 | self.assertEqual(int(FieldElement(17, 101) ** 89), 6) 128 | self.assertEqual(int(FieldElement(83, 101) ** 97), 35) 129 | self.assertEqual(int(FieldElement(64, 101) ** 30), 84) 130 | self.assertEqual(int(FieldElement(61, 101) ** 56), 56) 131 | self.assertEqual(int(FieldElement(61, 101) ** 9), 15) 132 | self.assertEqual(int(FieldElement(39, 101) ** 28), 84) 133 | self.assertEqual(int(FieldElement(40, 101) ** 32), 79) 134 | self.assertEqual(int(FieldElement(69, 101) ** 98), 65) 135 | self.assertEqual(int(FieldElement(74, 101) ** 56), 58) 136 | self.assertEqual(int(FieldElement(73, 101) ** 0), 1) 137 | self.assertEqual(int(FieldElement(8, 101) ** 86), 47) 138 | self.assertEqual(int(FieldElement(56, 101) ** 92), 16) 139 | self.assertEqual(int(FieldElement(60, 101) ** 25), 91) 140 | self.assertEqual(int(FieldElement(86, 101) ** 84), 56) 141 | self.assertEqual(int(FieldElement(94, 101) ** 11), 50) 142 | self.assertEqual(int(FieldElement(91, 101) + 52), 42) 143 | self.assertEqual(int(FieldElement(75, 101) + 79), 53) 144 | self.assertEqual(int(FieldElement(42, 101) + 43), 85) 145 | self.assertEqual(int(FieldElement(75, 101) + 82), 56) 146 | self.assertEqual(int(FieldElement(99, 101) + 63), 61) 147 | self.assertEqual(int(FieldElement(10, 101) + 49), 59) 148 | self.assertEqual(int(FieldElement(8, 101) + 49), 57) 149 | self.assertEqual(int(FieldElement(74, 101) + 81), 54) 150 | self.assertEqual(int(FieldElement(53, 101) + 19), 72) 151 | self.assertEqual(int(FieldElement(51, 101) + 65), 15) 152 | self.assertEqual(int(FieldElement(80, 101) + 56), 35) 153 | self.assertEqual(int(FieldElement(55, 101) + 61), 15) 154 | self.assertEqual(int(FieldElement(53, 101) + 80), 32) 155 | self.assertEqual(int(FieldElement(58, 101) + 2), 60) 156 | self.assertEqual(int(FieldElement(96, 101) + 74), 69) 157 | self.assertEqual(int(FieldElement(83, 101) + 93), 75) 158 | self.assertEqual(int(FieldElement(17, 101) - 27), 91) 159 | self.assertEqual(int(FieldElement(34, 101) - 1), 33) 160 | self.assertEqual(int(FieldElement(63, 101) - 23), 40) 161 | self.assertEqual(int(FieldElement(74, 101) - 76), 99) 162 | self.assertEqual(int(FieldElement(64, 101) - 65), 100) 163 | self.assertEqual(int(FieldElement(29, 101) - 25), 4) 164 | self.assertEqual(int(FieldElement(0, 101) - 69), 32) 165 | self.assertEqual(int(FieldElement(23, 101) - 40), 84) 166 | self.assertEqual(int(FieldElement(23, 101) - 46), 78) 167 | self.assertEqual(int(FieldElement(31, 101) - 67), 65) 168 | self.assertEqual(int(FieldElement(17, 101) - 100), 18) 169 | self.assertEqual(int(FieldElement(11, 101) - 22), 90) 170 | self.assertEqual(int(FieldElement(26, 101) - 6), 20) 171 | self.assertEqual(int(FieldElement(5, 101) - 21), 85) 172 | self.assertEqual(int(FieldElement(19, 101) - 48), 72) 173 | self.assertEqual(int(FieldElement(52, 101) - 34), 18) 174 | self.assertEqual(int(FieldElement(70, 101) // 84), 85) 175 | self.assertEqual(int(FieldElement(42, 101) // 92), 29) 176 | self.assertEqual(int(FieldElement(9, 101) // 11), 10) 177 | self.assertEqual(int(FieldElement(87, 101) // 28), 50) 178 | self.assertEqual(int(FieldElement(99, 101) // 10), 20) 179 | self.assertEqual(int(FieldElement(21, 101) // 89), 74) 180 | self.assertEqual(int(FieldElement(51, 101) // 29), 54) 181 | self.assertEqual(int(FieldElement(10, 101) // 99), 96) 182 | self.assertEqual(int(FieldElement(2, 101) // 64), 60) 183 | self.assertEqual(int(FieldElement(98, 101) // 79), 69) 184 | self.assertEqual(int(FieldElement(24, 101) // 6), 4) 185 | self.assertEqual(int(FieldElement(65, 101) // 34), 94) 186 | self.assertEqual(int(FieldElement(54, 101) // 59), 42) 187 | self.assertEqual(int(FieldElement(96, 101) // 55), 55) 188 | self.assertEqual(int(FieldElement(27, 101) // 94), 25) 189 | self.assertEqual(int(FieldElement(84, 101) // 36), 36) 190 | 191 | def test_exp_large(self): 192 | self.assertEqual(int(FieldElement(45329398547330232435475204068501392759, 170141183460469231731687303715884105727) ** 23973357120524123688767677450838423404), 110625867554914261405235347771839473528) 193 | self.assertEqual(int(FieldElement(11096317216645540333687625413300885798, 170141183460469231731687303715884105727) ** 18350067802502312484374146949394432005), 158114342748150869616337867244357893527) 194 | self.assertEqual(int(FieldElement(105193728357093738052129993765343901393, 170141183460469231731687303715884105727) ** 28949868692861977936123607826349169475), 97469690940520651844215943924110140562) 195 | self.assertEqual(int(FieldElement(111055120216185479216549737895719889955, 170141183460469231731687303715884105727) ** 116796601068080310567096901526856239558), 143288233252562942061753559724655924484) 196 | self.assertEqual(int(FieldElement(118573387676321580035191294408665717202, 170141183460469231731687303715884105727) ** 118468724281467837804867816531495356951), 25384169807760052976344572805881045078) 197 | self.assertEqual(int(FieldElement(8453841496330693524076697666656810794, 170141183460469231731687303715884105727) ** 50936640660640246195941254951084298956), 89980634104306998553990016030498527717) 198 | self.assertEqual(int(FieldElement(3126171733569194607538752261348981043, 170141183460469231731687303715884105727) ** 89540119583121092487935700750509976672), 76789997572366225883637242904225680866) 199 | self.assertEqual(int(FieldElement(87408682732145428292803410374197679069, 170141183460469231731687303715884105727) ** 73294773716505932813644442251790490252), 30190042501166266896046398631549945852) 200 | self.assertEqual(int(FieldElement(133656934690862077279671066447610175665, 170141183460469231731687303715884105727) ** 167537713805753850504640915450779147113), 35661701185378333693521640055115158413) 201 | self.assertEqual(int(FieldElement(98916010222012311006195259181587327980, 170141183460469231731687303715884105727) ** 43646275964617627585990852451242571176), 113494102718163694969171327315905227995) 202 | self.assertEqual(int(FieldElement(63972045063721755734341771679385747085, 170141183460469231731687303715884105727) ** 54196951232327114864338986457233698387), 45674328667154461933222295595156598033) 203 | self.assertEqual(int(FieldElement(30148817818891517113115639309493720746, 170141183460469231731687303715884105727) ** 79460949570435413221573946148779586587), 44923150826036815903390792324737278379) 204 | self.assertEqual(int(FieldElement(14365600219786747087436337553351351653, 170141183460469231731687303715884105727) ** 112788553884177448692041938153888362529), 66193098425771394236023545922584075435) 205 | self.assertEqual(int(FieldElement(107876445691250920950383433660235638727, 170141183460469231731687303715884105727) ** 63175031301901038638538102811208915385), 43293126929407246606869088225298896601) 206 | self.assertEqual(int(FieldElement(656600543513838100592447618947479104, 170141183460469231731687303715884105727) ** 9316063397339917001814241291992219008), 125439992161573737926617751254277143302) 207 | self.assertEqual(int(FieldElement(8515732054006400859632859854758105270, 170141183460469231731687303715884105727) ** 154793104050145597808664399207755838006), 80169600713538798061924004526058523555) 208 | self.assertEqual(int(FieldElement(136632104926671259150658557204382855307, 170141183460469231731687303715884105727) + 140120717775505985648375652851614073638), 106611639241708013067346906340112823218) 209 | self.assertEqual(int(FieldElement(38621638155689111539732260997177321764, 170141183460469231731687303715884105727) + 148910265184787996364066007383537138821), 17390719880007876172110964664830354858) 210 | self.assertEqual(int(FieldElement(104060080608448838825399857423116490745, 170141183460469231731687303715884105727) + 15866546562265594892647176808646907722), 119926627170714433718047034231763398467) 211 | self.assertEqual(int(FieldElement(135283065963309348867343419514142663254, 170141183460469231731687303715884105727) + 19283766952051149519051861565933157158), 154566832915360498386395281080075820412) 212 | self.assertEqual(int(FieldElement(129120665366701743301002608695639274872, 170141183460469231731687303715884105727) + 146665354566953345487941378645052581274), 105644836473185857057256683624807750419) 213 | self.assertEqual(int(FieldElement(30274191172009551312658490814045446047, 170141183460469231731687303715884105727) + 116086245620507866092530122516684873230), 146360436792517417405188613330730319277) 214 | self.assertEqual(int(FieldElement(92821078054382328459521199148602253460, 170141183460469231731687303715884105727) + 21453897095620677846008191705950115569), 114274975150003006305529390854552369029) 215 | self.assertEqual(int(FieldElement(113196838221973538581294430840107593118, 170141183460469231731687303715884105727) + 7120339564147990318433671914714064895), 120317177786121528899728102754821658013) 216 | self.assertEqual(int(FieldElement(69114258914682490045468116259427841467, 170141183460469231731687303715884105727) + 1991712575999046718015252192095523128), 71105971490681536763483368451523364595) 217 | self.assertEqual(int(FieldElement(109545890323014722350320179132149710664, 170141183460469231731687303715884105727) + 163857925843134909444560687945185850758), 103262632705680400063193563361451455695) 218 | self.assertEqual(int(FieldElement(71961452646098185936710794302606932344, 170141183460469231731687303715884105727) + 123269683332847795071057959722788502465), 25089952518476749276081450309511329082) 219 | self.assertEqual(int(FieldElement(77479169662442455854731274618943998038, 170141183460469231731687303715884105727) + 59269467271209903523116433439279610302), 136748636933652359377847708058223608340) 220 | self.assertEqual(int(FieldElement(4000584729672543964294135190189425293, 170141183460469231731687303715884105727) + 124633593148062781483437344640225262257), 128634177877735325447731479830414687550) 221 | self.assertEqual(int(FieldElement(44944448567903287336360285271047036054, 170141183460469231731687303715884105727) + 42934577016844380890687405816579749647), 87879025584747668227047691087626785701) 222 | self.assertEqual(int(FieldElement(15792232760272254417367391186546298212, 170141183460469231731687303715884105727) + 92629712458496110182888116723592226146), 108421945218768364600255507910138524358) 223 | self.assertEqual(int(FieldElement(16744519022997425945591286216498857854, 170141183460469231731687303715884105727) + 60097347038133774973283644794283514608), 76841866061131200918874931010782372462) 224 | self.assertEqual(int(FieldElement(106152913003121313917911941285262726732, 170141183460469231731687303715884105727) - 87195086898390730358371679807644887247), 18957826104730583559540261477617839485) 225 | self.assertEqual(int(FieldElement(45687281695846974635956411826165480656, 170141183460469231731687303715884105727) - 162213007661054927807473821400626255209), 53615457495261278560169894141423331174) 226 | self.assertEqual(int(FieldElement(15257030762745645948491801499137632857, 170141183460469231731687303715884105727) - 7418989103289055301648335264728502394), 7838041659456590646843466234409130463) 227 | self.assertEqual(int(FieldElement(106611804313960378162812847699836663716, 170141183460469231731687303715884105727) - 140665279939978230481300773387419903967), 136087707834451379413199378028300865476) 228 | self.assertEqual(int(FieldElement(133838733144617943706855944584448231448, 170141183460469231731687303715884105727) - 58467537767098938120996889592931844682), 75371195377519005585859054991516386766) 229 | self.assertEqual(int(FieldElement(95450444652509275212240754918440080423, 170141183460469231731687303715884105727) - 76033833226821264963537581552025667121), 19416611425688010248703173366414413302) 230 | self.assertEqual(int(FieldElement(55367802431278463738034647542577651919, 170141183460469231731687303715884105727) - 18005316014316544179988151202837054857), 37362486416961919558046496339740597062) 231 | self.assertEqual(int(FieldElement(125163033529513795858921820373190159377, 170141183460469231731687303715884105727) - 54475023212382152652298561017006898212), 70688010317131643206623259356183261165) 232 | self.assertEqual(int(FieldElement(64661737350159901732983806959842729302, 170141183460469231731687303715884105727) - 45176078586475432784323819536299959164), 19485658763684468948659987423542770138) 233 | self.assertEqual(int(FieldElement(107632274661578650916779608041071393978, 170141183460469231731687303715884105727) - 7589249240176203346240012712050723130), 100043025421402447570539595329020670848) 234 | self.assertEqual(int(FieldElement(164830283351449861312560615156382133149, 170141183460469231731687303715884105727) - 38881694406333428951872876266198212847), 125948588945116432360687738890183920302) 235 | self.assertEqual(int(FieldElement(145614266142808620579696974736201112667, 170141183460469231731687303715884105727) - 98440694630752268006876234464090231362), 47173571512056352572820740272110881305) 236 | self.assertEqual(int(FieldElement(64490301041749803164735778256826041594, 170141183460469231731687303715884105727) - 154475020120574089642783104165898103822), 80156464381644945253639977806812043499) 237 | self.assertEqual(int(FieldElement(115379742931322370510762640452114179672, 170141183460469231731687303715884105727) - 133011663520640094345715915522570422404), 152509262871151507896734028645427862995) 238 | self.assertEqual(int(FieldElement(130168725802159753553417756246748506660, 170141183460469231731687303715884105727) - 123362500924770089422799946293438475643), 6806224877389664130617809953310031017) 239 | self.assertEqual(int(FieldElement(38798461907097343442844080195939551410, 170141183460469231731687303715884105727) - 112708521425705507018391248752189820480), 96231123941861068156140135159633836657) 240 | self.assertEqual(int(FieldElement(169635720912393385456311228029418721549, 170141183460469231731687303715884105727) // 5125980552749438842852750418916796525), 107646814503452217117283843436202007165) 241 | self.assertEqual(int(FieldElement(107882884231390003679995023970257678803, 170141183460469231731687303715884105727) // 151763708725767129083405213066672737954), 82889642741106710193739689277845192084) 242 | self.assertEqual(int(FieldElement(94241150083544367565611230042352711183, 170141183460469231731687303715884105727) // 75036922656613131426921476208210274563), 153955148262808660845602842965393338168) 243 | self.assertEqual(int(FieldElement(100495636541697890794063010067874869700, 170141183460469231731687303715884105727) // 106212552742865435371691465447091858111), 102733954716615225361079724718408770035) 244 | self.assertEqual(int(FieldElement(108839390278524717297468354520537885106, 170141183460469231731687303715884105727) // 100040281751285786749878371784622849611), 9321205938575402744328233089858754436) 245 | self.assertEqual(int(FieldElement(117511643750848179104389378603022818870, 170141183460469231731687303715884105727) // 28480687143633577095730875558790621479), 57299652569101370544286329898224085396) 246 | self.assertEqual(int(FieldElement(114994670019423707745148692983614490300, 170141183460469231731687303715884105727) // 58187529989294639311237210961779471414), 147155163523377143250121888935297674289) 247 | self.assertEqual(int(FieldElement(107318671941012978233844525463904778624, 170141183460469231731687303715884105727) // 123654017802499232542387840704798462996), 106439330727364375694930105937996868447) 248 | self.assertEqual(int(FieldElement(132944172934937854746756050726407372454, 170141183460469231731687303715884105727) // 154276342736674962621014167992354449125), 27903634466374769281978778767278769694) 249 | self.assertEqual(int(FieldElement(25662843858972547447022692024664104224, 170141183460469231731687303715884105727) // 158748231144141156279066123094923903399), 29201388396028385555406537979410867836) 250 | self.assertEqual(int(FieldElement(113465879405035451701821832943645298828, 170141183460469231731687303715884105727) // 120460349755642205984621606946479112366), 71248519280901116320580234730652271391) 251 | self.assertEqual(int(FieldElement(8334941716861450887188645947309029530, 170141183460469231731687303715884105727) // 50138957532465094846999960859152732423), 101160997466615734206526379505805888684) 252 | self.assertEqual(int(FieldElement(26920812363722003034821933852333560994, 170141183460469231731687303715884105727) // 102212722464591334411157093773616161792), 25692793581031235137954843595156037418) 253 | self.assertEqual(int(FieldElement(134287335350600618899342739598509916590, 170141183460469231731687303715884105727) // 156617330166893666970965386415918144196), 144891184299551137640458323577893882867) 254 | self.assertEqual(int(FieldElement(128108665602581376305705079145332638442, 170141183460469231731687303715884105727) // 151184636384337255092177528680036397052), 7671040721822175495116587335138601275) 255 | self.assertEqual(int(FieldElement(14455986081875437153071558887236407967, 170141183460469231731687303715884105727) // 154668195530012920576141463919463625172), 157598580654627146019924599576602305897) 256 | -------------------------------------------------------------------------------- /construction-1/ecc/tests/FullTests.py: -------------------------------------------------------------------------------- 1 | # 2 | # joeecc - A small Elliptic Curve Cryptography Demonstration. 3 | # Copyright (C) 2011-2015 Johannes Bauer 4 | # 5 | # This file is part of joeecc. 6 | # 7 | # joeecc is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; this program is ONLY licensed under 10 | # version 3 of the License, later versions are explicitly excluded. 11 | # 12 | # joeecc is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with joeecc; if not, write to the Free Software 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | # 21 | # Johannes Bauer 22 | # 23 | 24 | from .FieldElementTests import FieldElementTests 25 | from .FieldElementSqrtTests import FieldElementSqrtTests 26 | from .ECTests import ECTests 27 | from .CryptoOpsTests import CryptoOpsTests 28 | from .CurveTests import CurveTests 29 | from .Ed25519BasicTests import Ed25519BasicTests 30 | from .Ed25519ExtdTests import Ed25519ExtdTests 31 | from .TwEdMontConversionTests import TwEdMontConversionTests 32 | from .TwEdMontDomainTests import TwEdMontDomainTests 33 | 34 | Ed25519ExtdTests.set_test_scope("full") 35 | -------------------------------------------------------------------------------- /construction-1/ecc/tests/TwEdMontConversionTests.py: -------------------------------------------------------------------------------- 1 | # 2 | # joeecc - A small Elliptic Curve Cryptography Demonstration. 3 | # Copyright (C) 2011-2015 Johannes Bauer 4 | # 5 | # This file is part of joeecc. 6 | # 7 | # joeecc is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; this program is ONLY licensed under 10 | # version 3 of the License, later versions are explicitly excluded. 11 | # 12 | # joeecc is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with joeecc; if not, write to the Free Software 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | # 21 | # Johannes Bauer 22 | # 23 | 24 | import unittest 25 | import random 26 | from .. import getcurvebyname 27 | 28 | class TwEdMontConversionTests(unittest.TestCase): 29 | def setUp(self): 30 | self._mont = getcurvebyname("curve25519") 31 | self._twed = getcurvebyname("ed25519") 32 | 33 | def test_generator(self): 34 | Ge = self._twed.G 35 | self.assertEqual(Ge.convert(self._mont), self._mont.G) 36 | 37 | Gm = self._mont.G 38 | self.assertEqual(Gm.convert(self._twed), self._twed.G) 39 | 40 | def test_neutral(self): 41 | Oe = self._twed.neutral() 42 | self.assertEqual(Oe.convert(self._mont), self._mont.neutral()) 43 | 44 | Om = self._mont.neutral() 45 | self.assertEqual(Om.convert(self._twed), self._twed.neutral()) 46 | 47 | def test_scalar_conv_twed_to_mont(self): 48 | for i in range(2, 1000, 17): 49 | Pe = self._twed.G * i 50 | Pm = self._mont.G * i 51 | self.assertEqual(Pe.convert(self._mont), Pm) 52 | 53 | def test_scalar_conv_mont_to_twed(self): 54 | for i in range(2, 1000, 17): 55 | Pe = self._twed.G * i 56 | Pm = self._mont.G * i 57 | self.assertEqual(Pm.convert(self._twed), Pe) 58 | 59 | def test_random_ptadds(self): 60 | P = self._twed.G 61 | scalar = 1 62 | self.assertEqual(P, self._twed.G * scalar) 63 | for i in range(20): 64 | P = P.convert(self._mont) 65 | self.assertEqual(P, self._mont.G * scalar) 66 | 67 | r = random.randint(2 ** 32, 2 ** 64) 68 | Q = self._mont.G * r 69 | P = P + Q 70 | scalar += r 71 | self.assertEqual(P, self._mont.G * scalar) 72 | 73 | P = P.convert(self._twed) 74 | self.assertEqual(P, self._twed.G * scalar) 75 | 76 | r = random.randint(2 ** 32, 2 ** 64) 77 | Q = self._twed.G * r 78 | P = P + Q 79 | scalar += r 80 | self.assertEqual(P, self._twed.G * scalar) 81 | -------------------------------------------------------------------------------- /construction-1/ecc/tests/TwEdMontDomainTests.py: -------------------------------------------------------------------------------- 1 | # 2 | # joeecc - A small Elliptic Curve Cryptography Demonstration. 3 | # Copyright (C) 2011-2015 Johannes Bauer 4 | # 5 | # This file is part of joeecc. 6 | # 7 | # joeecc is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; this program is ONLY licensed under 10 | # version 3 of the License, later versions are explicitly excluded. 11 | # 12 | # joeecc is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with joeecc; if not, write to the Free Software 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | # 21 | # Johannes Bauer 22 | # 23 | 24 | import unittest 25 | import random 26 | from .. import getcurvebyname 27 | 28 | class TwEdMontDomainTests(unittest.TestCase): 29 | def setUp(self): 30 | self._mont = getcurvebyname("curve25519") 31 | self._twed = getcurvebyname("ed25519") 32 | 33 | def test_twed_to_mont(self): 34 | mont = self._twed.to_montgomery(b = int(self._mont.b)) 35 | self.assertEqual(mont.domainparams, self._mont.domainparams) 36 | 37 | def test_mont_to_twed(self): 38 | twed = self._mont.to_twistededwards(a = int(self._twed.a)) 39 | self.assertEqual(twed.domainparams, self._twed.domainparams) 40 | -------------------------------------------------------------------------------- /construction-1/ecc/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # joeecc - A small Elliptic Curve Cryptography Demonstration. 3 | # Copyright (C) 2011-2015 Johannes Bauer 4 | # 5 | # This file is part of joeecc. 6 | # 7 | # joeecc is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; this program is ONLY licensed under 10 | # version 3 of the License, later versions are explicitly excluded. 11 | # 12 | # joeecc is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with joeecc; if not, write to the Free Software 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | # 21 | # Johannes Bauer 22 | # 23 | 24 | from .FieldElementTests import FieldElementTests 25 | from .FieldElementSqrtTests import FieldElementSqrtTests 26 | from .ECTests import ECTests 27 | from .CryptoOpsTests import CryptoOpsTests 28 | from .CurveTests import CurveTests 29 | from .Ed25519BasicTests import Ed25519BasicTests 30 | from .Ed25519ExtdTests import Ed25519ExtdTests 31 | from .TwEdMontConversionTests import TwEdMontConversionTests 32 | from .TwEdMontDomainTests import TwEdMontDomainTests 33 | -------------------------------------------------------------------------------- /construction-1/kill.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | 3 | def subprocess_cmd(command): 4 | process = subprocess.Popen(command,stdout=subprocess.PIPE, shell=True) 5 | proc_stdout = process.communicate()[0].strip() 6 | print proc_stdout 7 | return proc_stdout 8 | 9 | cmd = "ps -x | grep python" 10 | resp = subprocess_cmd(cmd) 11 | lines = resp.split("\n") 12 | #print lines 13 | pids = "" 14 | for i in lines: 15 | print i 16 | if "ttys" in i: 17 | pid, _ = i.split("ttys") 18 | elif "pts" in i: 19 | pid, _ = i.split("pts") 20 | elif "?" in i: 21 | pid, _ = i.split("?") 22 | pids += pid 23 | 24 | #for Mac 25 | cmd = "kill " + pids 26 | 27 | #for Linux 28 | #cmd = "kill -9 " + pids 29 | 30 | print cmd 31 | resp = subprocess_cmd(cmd) 32 | --------------------------------------------------------------------------------