---------- Forwarded message --------- From: Pedro.Cosme Vieira <pedro.cosme.vie...@gmail.com> Date: Thu, Aug 22, 2024 at 9:22 PM Subject: Re: Anonymous routing with encrypted IP addresses (Initial Internet Draft) To: Alvaro Retana <aretana.i...@gmail.com>
Thank you very much Alvaro, I am sending it again using Markdown. Best regard On Thu, Aug 22, 2024 at 8:40 PM Alvaro Retana <aretana.i...@gmail.com> wrote: > Pedro: > > Hi! > > For context for everyone else, I’m repeating here part of what I send in > response to your message to the IAB: > > ===== > ... > In any case, proposals for changes should be sent to an IETF working group > (not the IAB). In this case, because the proposal includes changes to > addressing and routing, you may want to consider engaging with the Routing > Area WG [1] or the Internet Area WG [2]. In either case, please use the > Internet-Draft format for a submission [3]. > > Thanks! > > Alvaro. > > [1] https://datatracker.ietf.org/group/rtgwg/about/ > [2] https://datatracker.ietf.org/group/intarea/about/ > [3] https://authors.ietf.org/ > ===== > > > To be clear. For a proposal to be considered a contribution to the IETF > and be discussed, it should be submitted in the Internet-draft format and > not as a PDF. > > Look at link [3] above. That site contains an overview of the process and > detailed instructions on how to write and submit an ID (search for "Getting > started”). > > Alvaro. > > On August 22, 2024 at 9:43:30 AM, Pedro.Cosme Vieira ( > pedro.cosme.vie...@gmail.com) wrote: > > Dear Jim Guichard, Jeff Tantsura, Yingzhen Qu, Éric Vyncke, Juan-Carlos > Zúñiga, and Wassim Haddad, > > I previously contacted Alvaro Retana, who advised me to better explain the > algorithm and suggested that I reach out to you. I apologize if you find > the details to be very basic, but my intent is simply to make it clear that > it works perfectly. > > I have an Initial Internet Draft that proposes a new addressing scheme > using an encrypted IP with ECDH, called IPy, to make it impossible to track > and block a particular server using its IP address. > > The 128-bit encrypted address makes it computationally impossible for any > router to identify the sender and receiver of the packet. Given that this > is a current issue, with governments blocking important companies like > Google, WhatsApp, and ChatGPT, I hope it piques your curiosity. > > The algorithm is simple but requires greater computational power from > network cards, which, instead of just reading the IP to identify if it is > theirs, must decrypt the IPy address. > > Best regards, > Pedro Cosme > _______________________________________________ > rtgwg mailing list -- rtgwg@ietf.org > To unsubscribe send an email to rtgwg-le...@ietf.org > >
# Internet Draft **Name: Anonymous routing with encrypted IP addresses** *Author: Pedro Cosme Vieira* *Date: 22 August 2024* **Summary:** When the Internet was created, publicly visible addressing was necessary, which allows for the collection of metadata and enables certain countries to block specific private servers. For example, Google, WhatsApp, and ChatGPT are blocked in China. My proposal is to use ECDH to encrypt IP addresses, IPy, making it impossible to identify servers and clients, and consequently, preventing server blocking and metadata collection through IP addresses. ## 1. Introduction When a Client has secure access to the Server's public key, it is possible to establish a fully encrypted connection using ECDH-P256. However, IP addresses remain unencrypted, making it possible to log traffic metadata (origin, destination and volume) and to block connections to specific servers. For instance, Google, WhatsApp, and ChatGPT are blocked in China. The initial implementation of the WWW was modeled after telephone lines, where a call must have a source and destination number. Based on this model, the 32-bit IPv4 (RFC 971) was introduced in 1982, followed by the 128-bit IPv6 (RFC 8200) in 2017. Given this model and the limitations of routers, messages could only be addressed if the source and destination IP addresses were fixed, easily readable, and to compute. My proposal requires significantly more computational power from routers and network interfaces, and more information exchange. This is feasible because, between 1982 and today, computational capacity per euro (and information exchange capability) has increased a million-fold. ## 2. LAN = Ethernet and MAC Address In a hub-based Ethernet network, all devices connected to the network can "hear" all the data packets transmitted over the physical medium. Each device has a unique MAC address, which is used to identify every device on the network. For example, if the network has devices 0, 1, 2, , E, F on the network, when device 5 wants to send a packet to device C, the hub sends it to all devices. The message starts with the destination and source MAC addresses, [C: 5: Message] and, although all devices can read the packet, only device C is interested in processing the message. When device 5 has secure access to the public key of device C, the packet may be encrypted using ECDH-P256 but the MAC addresses remain unencrypted, making it possible to log traffic metadata (origin, destination, and volume) and to block connections to specific devices. When a switch is used, the network is divided so that only a portion of the devices can hear the packet. The switch has a table, the MAC Address Table, which identifies the port to which it should send the packet. If the switch wants, it can collect the metadata and even block packets sent to or from device C from all devices. ### A network where packets addresses are encrypted random numbers When device 5 wants to send a packet to device C, it creates a random address for itself, for example, 298343. It also creates a random number, RN, and a checksum, CS, for example, CS = 3^RN % D where D is a prime number. RN = 167, D = 251 => CS = 3^RN % D = 121. The number RNCS = 167121 created by device 5 is fundamental for addressing but cannot yet be used as an address because device C is not aware of this number. Device 5 must encrypt the number 167121 in such a way that only device C understands that the message is intended for it. Each device has a public key, PubK0, PubK1, ..., PubKF, and device 5 will encrypt 167121 with the public key PubKC, which results in, e.g., 578493, and will use this number as the address for device C. The handshake packet will be [578493: 298343: Message] When the packet reaches the switch, the addresses are not in the MAC Address Table (the switch does not know the devices where it comes from or where it is going to). So, it creates the return entry 298343/P3 and has to forward the packet to all ports (flooding). All devices will decrypt the address with their private key, but only device C's private key, PriKC, will yield RN=167 and CS=121, making CS = 3^RN % D true. Since device C was able to decrypt the address, it responds to the switch saying "I'm the 578493" and the switch creates the entry 578493/P5 in the MAC Address Table. ### The switch is unable to identify where there is a packet to or from the device C Device C has the address 578493 in packets sent by device 5 but has a different, random address, in packets sent by other devices, e.g., 395016, 195473, or 338695. Additionally, whenever the switch identifies and blocks device C, device 5 will change the address. Anonymity of devices comes with a computational cost because network cards must decrypt the addresses of all packets to check if they are intended for them, and the switch has to update the MAC Address Table much more frequently. Additionally, the useful traffic on the network decreases because the switch needs to perform flooding whenever a connection is established. ## 3. The IP address is created and encrypted by the Client In a process similar to the one explained for MAC Addresses, the emitter will generate the IPy addresses of the receptor. Currently, the DNS - Domain Name System resolves domain names into IP addresses. To use encrypted addresses, the DNS will start resolving domain names into public keys. The emitter first generates a random number (RN) and calculates a checksum (CS) for this number. Using a 128-bit address (similar to IPv6), RN and CS will each have 64 bits, for example: RN = 15867496620714898897#random number D = 2**64 - 59 CS = pow(3,RN,D) RNCS = RN*2**64+CS print(RNCS) #to maintain secret RS=15867496620714898897 CS = 3535499274569942199 RNCS = 292703649252778898123667282343212909751 The RNCS number must be encrypted with the recipient's public key obtained from the DNS. If the DNS is forbidden from resolving the domain, the public key can be obtained alternatively, for example, via email or SMS. The receptor, e.g. Google, has a private and a public ECDH P-256 key, for example: priv_k_A = 3421517609221506784379601829815059467516362851066547338727633942844365292362 pub_k_A = 87210426579577415066249372883326866421523974240124183875210187907333176480275 The emitter also has a private and public key, for example: priv_k_B = 81958473207983658272724982349875710294785735698123810571065768475682841903 pub_k_B = 70615873030459876873763462891295230755237426729399447005370410798314324662441 Then, the client will calculate the ECDH shared key and use it to encrypt the RNCS: key_shared_B = f_shared_key(priv_key_B, pub_key_A_int) address_enc_int = dh.f_crypt_xor(RNCS, key_shared_B) The client's return address will be the least significant 128 bits of its public key: IPorigin = pubB_int % 2**128 And the message will also have the other half of the public key of the emitter: pubB_int // 2**128 The handshake packet contains the encrypted address of the receptor and the address and the public key of the emitter, all 128 bits numbers: [131129100730407958547162677077638961120:2087449374012893982 63835550736096073897:207521399564223783560145443489148971874: ] The routers will be unable to identify users. The addresses will not be assigned by a centralized entity, they will be dynamic, random, and multiple for each user. For example, a Google server will simultaneously have millions of different IPy addresses, one for each user. Consequently, routers will be unable to identify and block a particular user. Although there is a risk of having two identical addresses, a collision, with 128 bits the probability of that is very low. With a trillion active addresses simultaneously, the probability of having a collision is 10^-27. To identify the destination server, the router knows the public keys of all servers and the address 131129100730407958547162677077638961120. The problem of determining which public key corresponds to this encrypted address can only be solved by a brute-force attack (trying private keys until obtaining CS = 3^RN % D), which is computationally impossible with ECDH-256. ##4. Addressing with IPy, encrypted IP The destination address is read by routers where new random addresses are not in their address tables. Thus, all new addresses require flooding. When using flooding to identify the device with a certain IPy address, the process of communicating the path to routers typically involves the following steps: i) Flooding Process: Initially, a packet is broadcast to all nodes in the network (flooded) to discover the device with the specific IPy address. Every router or switch in the network receives this packet and forwards it to all its neighbours, except the one from which it was received. This process continues until the packet reaches the destination device. ii) Verify the address: All servers read the Client's public key, calculate the shared key, decrypt the address, and finally, verify if the number and checksum are correct: shared_key_A = vpInysWGs8uOVNOiQlRTV0nZkPqFGjm1wb+mZKc+Fa8 Where the pair RN/CS is correct, the handshake indicates that it is directed to that Server. iii) Response from the Destination Device: Once the packet reaches the device where the pair RN/CS is correct, that device sends a response packet back to the source. This response includes the IPy address, 131129100730407958547162677077638961120, and possibly additional identifying information. iv) Path Recording (Reverse Path Learning): As the response packet travels back to the source, each router or switch along the path records the next-hop information. This essentially creates a reverse path from the destination to the source. Routers use this information to establish a route back to the source. 131129100730407958547162677077638961120 <- - - - - -> 208744937401289398263835550736096073897 Decreasing computation and traffic requirements. Anonymity of devices comes with a computational cost because network cards must decrypt the addresses of all packets to check if they are intended for them, and the routers have to update the MAC Address Table much more frequently. To decreases computation and traffic requirements, we can use: i) The IPy address used repeatedly. Once user B establishes a connection with A, the IPy address is registered in the routers and can be used repeatedly, for example, for a week or a year (or until it is blocked). This reduces the number of new addresses that routers have to process. ii) The packet has a tag indicating it contains a new address. For example, the message is F0F0F0F0, and only if this tag is identified is the address decrypted and verified. iii) Part of the IPy address is unencrypted. The purpose of the encrypted address is to prevent the router from identifying a particular user. Therefore, the addresses may have an unencrypted portion that encodes a group/region where several users are located, for example, the first 16 bits. Router may identify that the packet goes to Oregon, Georgia, Virginia, North Carolina, or South Carolina, but it doesn't know that it is directed to a Google server (To block Google, they would have to block all the servers in these groups/regions). ##5. Python Code used to compute the example (it does not use any library): def f_format(mens_in,typein,typeout): "int <=> bin" typein,typeout = typein.lower(),typeout.lower() output = mens_in if typein != typeout: if (typein =="int") or (typein =="integer"): output=bin(mens_in)[2:] n=len(output) bytes = n // 8 if n % 8 > 0: bytes+=1 output = "0"*(bytes*8-n)+output if (typeout=="int") or (typeout=="integer"):#int output=int(output,2) return output def elliptic_curveP256():#P-256 global p,a,b,G,n p = int("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",16) a = int("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc",16) b = int("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",16) G = [int("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",16), int("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",16)] n = int("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",16) def f_sumGG(G, a, p): "G+G" numerator = 3 * G[0]**2 + a denominator = 2 * G[1] m = (numerator * pow(denominator,-1, p)) % p x3 = (m**2 - 2 * G[0]) % p y3 = (m * (G[0] - x3) - G[1]) % p return [x3,y3] def f_sumGX(G, X, p): "G+X, X != G" numerator = X[1] - G[1] denominator = X[0] - G[0] m = (numerator * pow(denominator,-1, p)) % p GplusX = (m**2 - G[0] - X[0]) % p GplusY = (m * (G[0] - GplusX) - G[1]) % p return [GplusX, GplusY] def f_multKG(k, G, a, p): number=k points=[] while number > 1: x=number//2 points.append([x,number%2]) number=x points=sorted(points) kG = G for point in points: kG = f_sumGG(kG, a, p) if point[1] == 1: kG = f_sumGX(kG, G, p) return kG def tonelli_shanks(n, p): def legendre_symbol(n, p): return pow(n, (p - 1) // 2, p) if p % 4 == 3: return pow(n, (p + 1) // 4, p) q = p - 1 s = 0 while q % 2 == 0: q //= 2 s += 1 z = 2 while legendre_symbol(z, p) != -1: z += 1 m = s c = pow(z, q, p) t = pow(n, q, p) r = pow(n, (q + 1) // 2, p) while t != 0 and t != 1: t2i = t i = 0 for i in range(1, m): t2i = pow(t2i, 2, p) if t2i == 1: break b = pow(c, 2 ** (m - i - 1), p) m = i c = pow(b, 2, p) t = (t * c) % p r = (r * b) % p return r def f_shared_key(priv_key_A,publ_key_B): x_value = publ_key_B rhs = (pow(x_value, 3, p) + a * x_value + b) % p y_value = tonelli_shanks(rhs, p) PubB = [x_value,y_value] shares_key_AB = f_multKG(priv_key_A,PubB,a,p)[0] return shares_key_AB def f_crypt_xor(mens_in,pass_in): "Encrypt mens_in with pass_in, both integer" mens_bin=f_format(mens_in,"int","bin") pass_bin=f_format(pass_in,"int","bin")[:len(mens_bin)] bin_encr = '' for b1, b2 in zip(mens_bin, pass_bin): # XOR bit a bit xor_result = int(b1) ^ int(b2) # XOR between two bits bin_encr += str(xor_result) return f_format(bin_encr,"bin","int") # Result ###start elliptic_curveP256() priv_key_A= 3421517609221506784379601829815059467516362851066547338727633942844365292362 pubA_int=f_multKG(priv_key_A,G,a,p)[0]#using ECDH print("PubA=",pubA_int) RS = 15867496620714898897 #random number D = 2**64 - 59 #prime number with 64 bits CS = pow(3,RS,D) #checksum of the random number RSCS = RS*2**64+CS #128 bits print(RS,CS,RSCS)#to mantain secret priv_key_B= 81958473207983658272724982349875710294785735698123810571065768475682841903 pubB_int=f_multKG(priv_key_B,G,a,p)[0] print("Pub_key_B=",pubB_int) #will be sent to server as two 128 bits numbers key_shared_B = f_shared_key(priv_key_B,pubA_int) address_enc_int = f_crypt_xor(RSCS,key_shared_B) handshake = f"{address_enc_int}:{pubB_int % 2**128}:{pubB_int // 2**128}" print(f"Handshake = {handshake}") address_enc, pubB_int1,pubB_int2 = handshake.split(":") address_enc_int = int(address_enc) pubB_int = int(pubB_int2)*2**128+ int(pubB_int1) key_shared_A = f_shared_key(priv_key_A,pubB_int) address_des_int = f_crypt_xor(address_enc_int,key_shared_A) RN= address_des_int // 2**64 SC= address_des_int % 2**64 divisor=2**64-59 checksum_int = pow(3,RN,divisor) print(f"Is the message to me? {checksum_int ==SC}.") if checksum_int ==SC: print("Server sends a response packet back to the source") #another server desencrypts the address with its private key but fails priv_key_C= 4859187284385845045596843871069583621287459869696582381920438667382910219381 key_shared_C = f_shared_key(priv_key_C,pubB_int) address_des_int = f_crypt_xor(address_enc_int,key_shared_C) RN= address_des_int // 2**64 SC= address_des_int % 2**64 divisor=2**64-59 checksum_int = pow(3,RN,divisor) print(f"Is the message to me? {checksum_int ==SC}.") if checksum_int ==SC: print("Server sends a response packet back to the source") Output: Is the message to me? True. Server sends a response packet back to the source Is the message to me? False. #END
_______________________________________________ rtgwg mailing list -- rtgwg@ietf.org To unsubscribe send an email to rtgwg-le...@ietf.org