This commit is contained in:
jimbo 2021-07-30 21:34:50 +00:00
commit 7f997af8a6
6 changed files with 618 additions and 0 deletions

94
README.md Normal file
View File

@ -0,0 +1,94 @@
main reference:
- https://zeronet.io
- V3 mirror http://zeronet34m3r5ngdu54uj57dcafpgdjhxsgq5kla5con4qvcmfzpvhad.onion
- https://github.com/HelloZeroNet/ZeroNet
# V3 Hidden Service support
sadly script with small patch to integrate support for hidden (onion) service V3 on ZeroNet darknet.
this patch refers these issue:
- https://github.com/HelloZeroNet/ZeroNet/issues/2351
- https://github.com/HelloZeroNet/ZeroNet/issues/1292
- or from ZeroNet [GitCenter](http://127.0.0.1:43110/1GitLiXB6t5r8vuU2zC6a8GYj9ME6HMQ4t/repo/issues/view/?1P4w4Rvh4vS9r6G5xTiSh8qEW87EKZtnJB/9@1DfrA2M9Qra6stqT6tzwNMYNweswY54KAC)
In particular it manages the tracker function ( bootstrap plugin enable ) verifying and distributing onion V3 peers to others ( to both patched and unpatched clients ).
As you may know the hiddien service V2 are deprecated and in October will cease to exist permanently, is why in the transition phase (wait for V3 support to be released from the official repo) it's important to enable the boostrap plugin (and add v3 trackers in bootstrap list) to verify and share OnionV3 peers that cannot be verified by current trackers with the stable version.
For the installation guide i will use a fresh new client, following the installation guide on the official repo : https://github.com/HelloZeroNet/ZeroNet
### Linux (x86-64bit)
- `wget https://github.com/HelloZeroNet/ZeroNet-linux/archive/dist-linux64/ZeroNet-py3-linux64.tar.gz`
- `tar xvpfz ZeroNet-py3-linux64.tar.gz`
- `cd ZeroNet-linux-dist-linux64/`
now move inside core/ dir and download this repo
- `cd core`
- `git clone https://git.disroot.org/anonymoose/ZeroNet_OnionV3.git`
move inside downloaded folder and launch `install.sh` script.
- `cd ZeroNet_OnionV3`
- `./install.sh`
back to main folder
- `cd ../..`
now the client is enabled to support V3 hidden services
you can launch the client normally from ZeroNet-linux-dist-linux64
- `./ZeroNet.sh`
---
## Tor configuration and tracker settings
if you want to start immediately in tracker - tor always mode these are configurations tested on debian10, more information can be found in the official FAQ:
- https://zeronet.io/docs/faq/#how-to-use-zeronet-with-the-tor-browser
- https://zeronet.io/docs/faq/#how-to-use-zeronet-with-tor
for the use described the commands to follow for the configuration of Tor are described here:
https://zeronet.io/docs/faq/#how-to-make-zeronet-work-with-tor-under-linuxmacos
- `sudo nano /etc/tor/torrc`
- remove `#` character from lines `ControlPort 9051` and `CookieAuthentication 1`
- restart tor : `sudo service tor restart`
- add permission for yourself to read the auth cookie. with Debian Linux, the command is `sudo usermod -a -G debiantor [yourlinuxuser]` (if you are not on Debian check the file's user group by `ls -al /var/run/tor/control.authcookie`)
- logout/login with your user to apply group changes
- add a `zeronet.conf` on ZeroNet-linux-dist-linux64 with
```
[global]
tor = always
```
- enable tracker plugin, always from ZeroNet-linux-dist-linux64
`mv core/plugins/disabled-Bootstrapper core/plugins/Bootstrapper`
- launch `./ZeroNet.sh`
---
## Tips
v3 tracker to add in bootstrap list:
- `zero://tnjppdoc4famqa62mldlzc3fqw2wlsfxov7iz3pz5ex6umnqpaupflqd.onion:16227`
Syncronite trackers file list :
- http://127.0.0.1:43110/15CEFKBRHFfAP9rmL6hhLmHoXrrgmw4B5o
---
## Todo
- understand why onion addresses aren't shared as shared trackers
- permanent tracker onion address
- upgrade plugins/StemPort for V3 support
- default stem lib for manage hidden services
## Patch explained
This patch doesn't definitively differentiate onion v2 from v3, via `CryptRsa.py` I've maintained the v2 functions unchanged and added a copy of those funcionts ( sign, verify key .. ) with library required by onion v3 (`Ed25519.py`), recognising the type of address version from the length of the hidden service keys used in the functions ( definitely could be improved! ).
## Script explained
- move `upgrade_file/CryptEd25519.py` and `upgrade_file/CryptRsa.py` to `ZeroPath/src/Crypt/`
- replace in `ZeroPath/src/Tor/TorManager.py` the 2 words `RSA1024` with `ED25519-V3`
- add the line to the top:
`from Crypt import CryptEd25519` to :
- `ZeroPath/src/Tor/TorManager.py`
- `ZeroPath/plugins/AnnounceZero/AnnounceZeroPlugin.py`
works

94
backup_file/README.md Normal file
View File

@ -0,0 +1,94 @@
main reference:
- https://zeronet.io
- V3 mirror http://zeronet34m3r5ngdu54uj57dcafpgdjhxsgq5kla5con4qvcmfzpvhad.onion
- https://github.com/HelloZeroNet/ZeroNet
# V3 Hidden Service support
sadly script with small patch to integrate support for hidden (onion) service V3 on ZeroNet darknet.
this patch refers these issue:
- https://github.com/HelloZeroNet/ZeroNet/issues/2351
- https://github.com/HelloZeroNet/ZeroNet/issues/1292
- or from ZeroNet [GitCenter](http://127.0.0.1:43110/1GitLiXB6t5r8vuU2zC6a8GYj9ME6HMQ4t/repo/issues/view/?1P4w4Rvh4vS9r6G5xTiSh8qEW87EKZtnJB/9@1DfrA2M9Qra6stqT6tzwNMYNweswY54KAC)
In particular it manages the tracker function ( bootstrap plugin enable ) verifying and distributing onion V3 peers to others ( to both patched and unpatched clients ).
As you may know the hiddien service V2 are deprecated and in October will cease to exist permanently, is why in the transition phase (wait for V3 support to be released from the official repo) it's important to enable the boostrap plugin (and add v3 trackers in bootstrap list) to verify and share OnionV3 peers that cannot be verified by current trackers with the stable version.
For the installation guide i will use a fresh new client, following the installation guide on the official repo : https://github.com/HelloZeroNet/ZeroNet
### Linux (x86-64bit)
- `wget https://github.com/HelloZeroNet/ZeroNet-linux/archive/dist-linux64/ZeroNet-py3-linux64.tar.gz`
- `tar xvpfz ZeroNet-py3-linux64.tar.gz`
- `cd ZeroNet-linux-dist-linux64/`
now move inside core/ dir and download this repo
- `cd core`
- `git clone xxx`
move inside downloaded folder and launch `install.sh` script.
- `cd xxx`
- `./install.sh`
back to main folder
- `cd ../..`
now the client is enabled to support V3 hidden services
you can launch the client normally from ZeroNet-linux-dist-linux64
- `./ZeroNet.sh`
---
## Tor configuration and tracker settings
if you want to start immediately in tracker - tor always mode these are configurations tested on debian10, more information can be found in the official FAQ:
- https://zeronet.io/docs/faq/#how-to-use-zeronet-with-the-tor-browser
- https://zeronet.io/docs/faq/#how-to-use-zeronet-with-tor
for the use described the commands to follow for the configuration of Tor are described here:
https://zeronet.io/docs/faq/#how-to-make-zeronet-work-with-tor-under-linuxmacos
- `sudo nano /etc/tor/torrc`
- remove `#` character from lines `ControlPort 9051` and `CookieAuthentication 1`
- restart tor : `sudo service tor restart`
- add permission for yourself to read the auth cookie. with Debian Linux, the command is `sudo usermod -a -G debiantor [yourlinuxuser]` (if you are not on Debian check the file's user group by `ls -al /var/run/tor/control.authcookie`)
- logout/login with your user to apply group changes
- add a `zeronet.conf` on ZeroNet-linux-dist-linux64 with
```
[global]
tor = always
```
- enable tracker plugin, always from ZeroNet-linux-dist-linux64
`mv core/plugins/disabled-Bootstrapper core/plugins/Bootstrapper`
- launch `./ZeroNet.sh`
---
## Tips
v3 tracker to add in bootstrap list:
- `zero://tnjppdoc4famqa62mldlzc3fqw2wlsfxov7iz3pz5ex6umnqpaupflqd.onion:16227i`
Syncronite trackers file list :
- http://127.0.0.1:43110/15CEFKBRHFfAP9rmL6hhLmHoXrrgmw4B5o
---
## Todo
- understand why onion addresses aren't shared as shared trackers
- permanent tracker onion address
- upgrade plugins/StemPort for V3 support
- default stem lib for manage hidden services
## Patch explained
This patch doesn't definitively differentiate onion v2 from v3, via `CryptRsa.py` I've maintained the v2 functions unchanged and added a copy of those funcionts ( sign, verify key .. ) with library required by onion v3 (`Ed25519.py`), recognising the type of address version from the length of the hidden service keys used in the functions ( definitely could be improved! ).
## Script explained
- move `upgrade_file/CryptEd25519.py` and `upgrade_file/CryptRsa.py` to `ZeroPath/src/Crypt/`
- replace in `ZeroPath/src/Tor/TorManager.py` the 2 words `RSA1024` with `ED25519-V3`
- add the line :
`from Crypt import CryptEd25519` to :
- `ZeroPath/src/Tor/TorManager.py`
- `ZeroPath/plugins/AnnounceZero/AnnounceZeroPlugin.py`
works

13
install.sh Executable file
View File

@ -0,0 +1,13 @@
#!/bin/bash
if [ -d $PWD/../src/ ]
then
sed -i '/from Crypt import CryptRsa/a from Crypt import CryptEd25519' $PWD/../src/Tor/TorManager.py
sed -i '/from Crypt import CryptRsa/a from Crypt import CryptEd25519' $PWD/../plugins/AnnounceZero/AnnounceZeroPlugin.py
sed -i 's/RSA1024/ED25519-V3/g' $PWD/../src/Tor/TorManager.py
cp $PWD/../src/Crypt/CryptRsa.py $PWD/backup_file/CryptRsa.py
cp $PWD/upgrade_file/CryptRsa.py $PWD/../src/Crypt/CryptRsa.py
cp $PWD/upgrade_file/CryptEd25519.py $PWD/../src/Crypt/CryptEd25519.py
echo "Good, all done!"
else
echo "! I was not executed in the right place"
fi

12
restore.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash
if [ -d $PWD/../src/ ]
then
sed -i '/from Crypt import CryptEd25519/d' $PWD/../src/Tor/TorManager.py
sed -i '/from Crypt import CryptEd25519/d' $PWD/../plugins/AnnounceZero/AnnounceZeroPlugin.py
sed -i 's/ED25519-V3/RSA1024/g' $PWD/../src/Tor/TorManager.py
cp $PWD/backup_file/CryptRsa.py $PWD/../src/Crypt/CryptRsa.py
rm $PWD/../src/Crypt/CryptEd25519.py
echo "Good, all restored!"
else
echo "! I was not executed in the right place"
fi

View File

@ -0,0 +1,340 @@
## ZeroNet onion V3 support
## The following copied code is copied from stem.util.ed25519 official Tor Project python3 lib
## url : https://gitweb.torproject.org/stem.git/tree/stem/util/ed25519.py
## the ##modified tag means that the function has been modified respect to the one used by stem lib
## the ##custom tag means that the function has been added by me and it's not present on the stem ed25519.py file
## every comment i make begins with ##
##
# The following is copied from...
#
# https://github.com/pyca/ed25519
#
# This is under the CC0 license. For more information please see...
#
# https://github.com/pyca/cryptography/issues/5068
# ed25519.py - Optimized version of the reference implementation of Ed25519
#
# Written in 2011? by Daniel J. Bernstein <djb@cr.yp.to>
# 2013 by Donald Stufft <donald@stufft.io>
# 2013 by Alex Gaynor <alex.gaynor@gmail.com>
# 2013 by Greg Price <price@mit.edu>
#
# To the extent possible under law, the author(s) have dedicated all copyright
# and related and neighboring rights to this software to the public domain
# worldwide. This software is distributed without any warranty.
#
# You should have received a copy of the CC0 Public Domain Dedication along
# with this software. If not, see
# <http://creativecommons.org/publicdomain/zero/1.0/>.
"""
NB: This code is not safe for use with secret keys or secret data.
The only safe use of this code is for verifying signatures on public messages.
Functions for computing the public key of a secret key and for signing
a message are included, namely publickey_unsafe and signature_unsafe,
for testing purposes only.
The root of the problem is that Python's long-integer arithmetic is
not designed for use in cryptography. Specifically, it may take more
or less time to execute an operation depending on the values of the
inputs, and its memory access patterns may also depend on the inputs.
This opens it to timing and cache side-channel attacks which can
disclose data to an attacker. We rely on Python's long-integer
arithmetic, so we cannot handle secrets without risking their disclosure.
"""
import hashlib
import operator
import sys
import base64
__version__ = "1.0.dev0"
# Useful for very coarse version differentiation.
PY3 = sys.version_info[0] == 3
if PY3:
indexbytes = operator.getitem
intlist2bytes = bytes
int2byte = operator.methodcaller("to_bytes", 1, "big")
else:
int2byte = chr
range = xrange
def indexbytes(buf, i):
return ord(buf[i])
def intlist2bytes(l):
return b"".join(chr(c) for c in l)
b = 256
q = 2 ** 255 - 19
l = 2 ** 252 + 27742317777372353535851937790883648493
def H(m):
return hashlib.sha512(m).digest()
def pow2(x, p):
"""== pow(x, 2**p, q)"""
while p > 0:
x = x * x % q
p -= 1
return x
def inv(z):
"""$= z^{-1} \mod q$, for z != 0"""
# Adapted from curve25519_athlon.c in djb's Curve25519.
z2 = z * z % q # 2
z9 = pow2(z2, 2) * z % q # 9
z11 = z9 * z2 % q # 11
z2_5_0 = (z11 * z11) % q * z9 % q # 31 == 2^5 - 2^0
z2_10_0 = pow2(z2_5_0, 5) * z2_5_0 % q # 2^10 - 2^0
z2_20_0 = pow2(z2_10_0, 10) * z2_10_0 % q # ...
z2_40_0 = pow2(z2_20_0, 20) * z2_20_0 % q
z2_50_0 = pow2(z2_40_0, 10) * z2_10_0 % q
z2_100_0 = pow2(z2_50_0, 50) * z2_50_0 % q
z2_200_0 = pow2(z2_100_0, 100) * z2_100_0 % q
z2_250_0 = pow2(z2_200_0, 50) * z2_50_0 % q # 2^250 - 2^0
return pow2(z2_250_0, 5) * z11 % q # 2^255 - 2^5 + 11 = q - 2
d = -121665 * inv(121666) % q
I = pow(2, (q - 1) // 4, q)
def xrecover(y):
xx = (y * y - 1) * inv(d * y * y + 1)
x = pow(xx, (q + 3) // 8, q)
if (x * x - xx) % q != 0:
x = (x * I) % q
if x % 2 != 0:
x = q-x
return x
By = 4 * inv(5)
Bx = xrecover(By)
B = (Bx % q, By % q, 1, (Bx * By) % q)
ident = (0, 1, 1, 0)
def edwards_add(P, Q):
# This is formula sequence 'addition-add-2008-hwcd-3' from
# http://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
(x1, y1, z1, t1) = P
(x2, y2, z2, t2) = Q
a = (y1-x1)*(y2-x2) % q
b = (y1+x1)*(y2+x2) % q
c = t1*2*d*t2 % q
dd = z1*2*z2 % q
e = b - a
f = dd - c
g = dd + c
h = b + a
x3 = e*f
y3 = g*h
t3 = e*h
z3 = f*g
return (x3 % q, y3 % q, z3 % q, t3 % q)
def edwards_double(P):
# This is formula sequence 'dbl-2008-hwcd' from
# http://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
(x1, y1, z1, t1) = P
a = x1*x1 % q
b = y1*y1 % q
c = 2*z1*z1 % q
# dd = -a
e = ((x1+y1)*(x1+y1) - a - b) % q
g = -a + b # dd + b
f = g - c
h = -a - b # dd - b
x3 = e*f
y3 = g*h
t3 = e*h
z3 = f*g
return (x3 % q, y3 % q, z3 % q, t3 % q)
def scalarmult(P, e):
if e == 0:
return ident
Q = scalarmult(P, e // 2)
Q = edwards_double(Q)
if e & 1:
Q = edwards_add(Q, P)
return Q
# Bpow[i] == scalarmult(B, 2**i)
Bpow = []
def make_Bpow():
P = B
for i in range(253):
Bpow.append(P)
P = edwards_double(P)
make_Bpow()
def scalarmult_B(e):
"""
Implements scalarmult(B, e) more efficiently.
"""
# scalarmult(B, l) is the identity
e = e % l
P = ident
for i in range(253):
if e & 1:
P = edwards_add(P, Bpow[i])
e = e // 2
assert e == 0, e
return P
def encodeint(y):
bits = [(y >> i) & 1 for i in range(b)]
return b''.join([
int2byte(sum([bits[i * 8 + j] << j for j in range(8)]))
for i in range(b//8)
])
def encodepoint(P):
(x, y, z, t) = P
zi = inv(z)
x = (x * zi) % q
y = (y * zi) % q
bits = [(y >> i) & 1 for i in range(b - 1)] + [x & 1]
return b''.join([
int2byte(sum([bits[i * 8 + j] << j for j in range(8)]))
for i in range(b // 8)
])
def bit(h, i):
return (indexbytes(h, i // 8) >> (i % 8)) & 1
##modified
def publickey_unsafe(sk):
"""
Not safe to use with secret keys or secret data.
See module docstring. This function should be used for testing only.
"""
##h = H(sk)
h = sk
a = 2 ** (b - 2) + sum(2 ** i * bit(h, i) for i in range(3, b - 2))
A = scalarmult_B(a)
return encodepoint(A)
##custom
## from stem.util.str_tools._to_unicode_impl
## from https://gitweb.torproject.org/stem.git/tree/stem/util/str_tools.py#n80
def to_unicode_impl(msg):
if msg is not None and not isinstance(msg, str):
return msg.decode('utf-8', 'replace')
else:
return msg
##custom
## rewritten stem.descriptor.hidden_service.address_from_identity_key
## from https://gitweb.torproject.org/stem.git/tree/stem/descriptor/hidden_service.py#n1088
def publickey_to_onionaddress(key):
CHECKSUM_CONSTANT = b'.onion checksum'
## version = stem.client.datatype.Size.CHAR.pack(3)
version = b'\x03'
checksum = hashlib.sha3_256(CHECKSUM_CONSTANT + key + version).digest()[:2]
onion_address = base64.b32encode(key + checksum + version)
return to_unicode_impl(onion_address + b'.onion').lower()
def Hint(m):
h = H(m)
return sum(2 ** i * bit(h, i) for i in range(2 * b))
##modified
def signature_unsafe(m, sk, pk):
"""
Not safe to use with secret keys or secret data.
See module docstring. This function should be used for testing only.
"""
##h = H(sk)
h = sk
a = 2 ** (b - 2) + sum(2 ** i * bit(h, i) for i in range(3, b - 2))
r = Hint(
intlist2bytes([indexbytes(h, j) for j in range(b // 8, b // 4)]) + m
)
R = scalarmult_B(r)
S = (r + Hint(encodepoint(R) + pk + m) * a) % l
return encodepoint(R) + encodeint(S)
def isoncurve(P):
(x, y, z, t) = P
return (z % q != 0 and
x*y % q == z*t % q and
(y*y - x*x - z*z - d*t*t) % q == 0)
def decodeint(s):
return sum(2 ** i * bit(s, i) for i in range(0, b))
def decodepoint(s):
y = sum(2 ** i * bit(s, i) for i in range(0, b - 1))
x = xrecover(y)
if x & 1 != bit(s, b-1):
x = q - x
P = (x, y, 1, (x*y) % q)
if not isoncurve(P):
raise ValueError("decoding point that is not on curve")
return P
class SignatureMismatch(Exception):
pass
def checkvalid(s, m, pk):
"""
Not safe to use when any argument is secret.
See module docstring. This function should be used only for
verifying public signatures of public messages.
"""
if len(s) != b // 4:
raise ValueError("signature length is wrong")
if len(pk) != b // 8:
raise ValueError("public-key length is wrong")
R = decodepoint(s[:b // 8])
A = decodepoint(pk)
S = decodeint(s[b // 8:b // 4])
h = Hint(encodepoint(R) + pk + m)
(x1, y1, z1, t1) = P = scalarmult_B(S)
(x2, y2, z2, t2) = Q = edwards_add(R, scalarmult(A, h))
if (not isoncurve(P) or not isoncurve(Q) or
(x1*z2 - x2*z1) % q != 0 or (y1*z2 - y2*z1) % q != 0):
raise SignatureMismatch("signature does not pass verification")

65
upgrade_file/CryptRsa.py Normal file
View File

@ -0,0 +1,65 @@
import base64
import hashlib
def sign(data, privatekey):
import rsa
from rsa import pkcs1
from Crypt import CryptEd25519
## v3 = 88
if len(privatekey) == 88:
prv_key = base64.b64decode(privatekey)
pub_key = CryptEd25519.publickey_unsafe(prv_key)
sign = CryptEd25519.signature_unsafe(data, prv_key, pub_key)
return sign
if "BEGIN RSA PRIVATE KEY" not in privatekey:
privatekey = "-----BEGIN RSA PRIVATE KEY-----\n%s\n-----END RSA PRIVATE KEY-----" % privatekey
priv = rsa.PrivateKey.load_pkcs1(privatekey)
sign = rsa.pkcs1.sign(data, priv, 'SHA-256')
return sign
def verify(data, publickey, sign):
import rsa
from rsa import pkcs1
from Crypt import CryptEd25519
if len(publickey) == 32:
try:
valid = CryptEd25519.checkvalid(sign, data, publickey)
valid = 'SHA-256'
except Exception as err:
print(err)
valid = False
return valid
pub = rsa.PublicKey.load_pkcs1(publickey, format="DER")
try:
valid = rsa.pkcs1.verify(data, sign, pub)
except pkcs1.VerificationError:
valid = False
return valid
def privatekeyToPublickey(privatekey):
from Crypt import CryptEd25519
import rsa
from rsa import pkcs1
if len(privatekey) == 88:
prv_key = base64.b64decode(privatekey)
pub_key = CryptEd25519.publickey_unsafe(prv_key)
return pub_key
if "BEGIN RSA PRIVATE KEY" not in privatekey:
privatekey = "-----BEGIN RSA PRIVATE KEY-----\n%s\n-----END RSA PRIVATE KEY-----" % privatekey
priv = rsa.PrivateKey.load_pkcs1(privatekey)
pub = rsa.PublicKey(priv.n, priv.e)
return pub.save_pkcs1("DER")
def publickeyToOnion(publickey):
from Crypt import CryptEd25519
if len(publickey) == 32:
addr = CryptEd25519.publickey_to_onionaddress(publickey)[:-6]
return addr
return base64.b32encode(hashlib.sha1(publickey).digest()[:10]).lower().decode("ascii")