---------- Forwarded message ---------
From: Pedro.Cosme Vieira <[email protected]>
Date: Thu, Aug 22, 2024 at 9:22 PM
Subject: Re: Anonymous routing with encrypted IP addresses (Initial
Internet Draft)
To: Alvaro Retana <[email protected]>
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 <[email protected]>
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 (
> [email protected]) 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 -- [email protected]
> To unsubscribe send an email to [email protected]
>
>
# 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 -- [email protected]
To unsubscribe send an email to [email protected]