-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathanon_dappie.py
More file actions
157 lines (126 loc) · 6.28 KB
/
anon_dappie.py
File metadata and controls
157 lines (126 loc) · 6.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import time, options, log, sqlite3, ast, os, base64, re
import essentials
from Cryptodome.Signature import PKCS1_v1_5
from Cryptodome.Hash import SHA
from Cryptodome.PublicKey import RSA
from Cryptodome.Cipher import AES, PKCS1_OAEP
from decimal import *
from essentials import fee_calculate
config = options.Get()
config.read()
debug_level = config.debug_level_conf
ledger_path_conf = config.ledger_path_conf
full_ledger = config.full_ledger_conf
ledger_path = config.ledger_path_conf
hyper_path = config.hyper_path_conf
terminal_output=config.terminal_output
#(key, private_key_readable, public_key_readable, public_key_hashed, address) = keys.read() #import keys
key, public_key_readable, private_key_readable, _, _, public_key_hashed, address, keyfile = essentials.keys_load_new("wallet.der")
app_log = log.log("anon.log",debug_level,terminal_output)
def replace_regex(string,replace):
replaced_string = re.sub(r'^{}'.format(replace), "", string)
return replaced_string
def decrypt(encrypted):
cipher_aes_nonce, tag, ciphertext, enc_session_key = ast.literal_eval(encrypted)
with open("privkey.der", "r") as pk:
private_key = RSA.import_key(pk.read())
# Decrypt the session key with the public RSA key
cipher_rsa = PKCS1_OAEP.new(private_key)
session_key = cipher_rsa.decrypt(enc_session_key)
# Decrypt the data with the AES session key
cipher_aes = AES.new(session_key, AES.MODE_EAX, cipher_aes_nonce)
decrypted = cipher_aes.decrypt_and_verify(ciphertext, tag)
return decrypted
def randomize(divider, anon_amount, anon_recipient, identifier, anon_sender):
per_tx = int(anon_amount/divider) #how much per tx
tx_count = int(anon_amount/per_tx) #how many txs
remainder = anon_amount - per_tx*tx_count #remainder
print(divider, tx_count, per_tx, remainder, identifier, anon_sender)
anonymize(tx_count, per_tx, remainder, anon_recipient, identifier, anon_sender)
return
def anonymize(tx_count, per_tx, remainder, anon_recipient, identifier, anon_sender):
# return remainder to source!
a.execute("SELECT * FROM transactions WHERE openfield = ?", (identifier,))
try:
exists = a.fetchall()[0]
except:#if payout didn't happen yet
print(tx_count, per_tx, remainder, identifier)
for tx in range(tx_count):
#construct tx
openfield = "mixer"
operation = 0
fee = fee_calculate(openfield)
timestamp = '%.2f' % time.time()
transaction = (str(timestamp),
str(address),
str(anon_recipient),
'%.8f' % float(per_tx - fee),
str(operation),
str(openfield)) # this is signed
h = SHA.new(str(transaction).encode("utf-8"))
signer = PKCS1_v1_5.new(key)
signature = signer.sign(h)
signature_enc = base64.b64encode(signature)
print("Encoded Signature: {}".format(signature_enc.decode("utf-8")))
verifier = PKCS1_v1_5.new(key)
if verifier.verify(h, signature):
print("The signature is valid, proceeding to save transaction to mempool")
#construct tx
a.execute("INSERT INTO transactions VALUES (?,?,?,?,?,?,?,?)", (str(timestamp), str(address), str(anon_recipient), '%.8f' % float(per_tx - fee), str(signature_enc.decode("utf-8")), str(public_key_hashed), str(operation), str(identifier)))
anon.commit()
m.execute("INSERT INTO transactions VALUES (?,?,?,?,?,?,?,?)", (str(timestamp), str(address), str(anon_recipient), '%.8f' % float(per_tx - fee), str(signature_enc.decode("utf-8")), str(public_key_hashed), str(operation), str(openfield)))
mempool.commit()
if (remainder - fee) > 0:
openfield = "mixer"
operation = 0
fee = fee_calculate(openfield)
timestamp = '%.2f' % time.time()
transaction = (str(timestamp), str(address), str(anon_sender), '%.8f' % float(remainder - fee), str(operation), str(openfield)) # this is signed
m.execute("INSERT INTO transactions VALUES (?,?,?,?,?,?,?,?)", (str(timestamp), str(address), str(anon_sender), '%.8f' % float(remainder - fee), str(signature_enc.decode("utf-8")), str(public_key_hashed), str(operation), str(openfield)))
mempool.commit()
return
if not os.path.exists('anon.db'):
# create empty mempool
anon = sqlite3.connect('anon.db', timeout=1)
anon.text_factory = str
a = anon.cursor()
a.execute("CREATE TABLE IF NOT EXISTS transactions (timestamp, address, recipient, amount, signature, public_key, operation, openfield)")
anon.commit()
print("Created anon file")
anon = sqlite3.connect('anon.db')
anon.text_factory = str
a = anon.cursor()
if full_ledger == 1:
conn = sqlite3.connect(ledger_path)
else:
conn = sqlite3.connect(hyper_path)
conn.text_factory = str
c = conn.cursor()
mempool = sqlite3.connect('mempool.db')
mempool.text_factory = str
m = mempool.cursor()
while True:
try:
for row in c.execute("SELECT * FROM transactions WHERE recipient = ? and openfield LIKE ? LIMIT 500", (address,"enc="+'%',)):
anon_sender = row[2]
try:
#format: anon:number_of_txs:target_address (no msg, just encrypted)
print(row)
anon_recipient_encrypted = replace_regex(row[11], "enc=")
print(anon_recipient_encrypted)
anon_recipient = decrypt(anon_recipient_encrypted).decode("utf-8").split(":")[2]
print(anon_recipient)
divider = int(decrypt(anon_recipient_encrypted).decode("utf-8").split(":")[1])
if len(anon_recipient) == 56:
anon_amount = float(row[4])
identifier = row[5][:8] #only save locally
#print (anon_sender, anon_recipient, anon_amount, identifier)
randomize(divider, float(anon_amount), anon_recipient, identifier, anon_sender)
else:
print("Wrong target address length")
except Exception as e:
print(type(e), e)
except Exception as e:
print(e)
finally:
time.sleep(15)