---------- 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

Reply via email to