Use libsecp256k1 to sign.

Added 'Revoke' button to sent offers page.
This commit is contained in:
tecnovert 2020-12-11 09:11:35 +02:00
parent 8c372cc5dc
commit 49705f0974
No known key found for this signature in database
GPG key ID: 8ED6D8750C4E3F93
7 changed files with 76 additions and 25 deletions

View file

@ -4440,7 +4440,7 @@ class BasicSwap(BaseApp):
bids_received += r[2]
now = int(time.time())
q = self.engine.execute('SELECT COUNT(*) FROM offers WHERE expire_at > {}'.format(now)).first()
q = self.engine.execute('SELECT COUNT(*) FROM offers WHERE active_ind = 1 AND expire_at > {}'.format(now)).first()
num_offers = q[0]
q = self.engine.execute('SELECT COUNT(*) FROM offers WHERE was_sent = 1').first()

View file

@ -367,7 +367,13 @@ class HttpHandler(BaseHTTPRequestHandler):
show_bid_form = None
form_data = self.checkForm(post_string, 'offer', messages)
if form_data:
if b'newbid' in form_data:
if b'revoke_offer' in form_data:
try:
swap_client.revokeOffer(offer_id)
messages.append('Offer revoked')
except Exception as ex:
messages.append('Revoke offer failed ' + str(ex))
elif b'newbid' in form_data:
show_bid_form = True
else:
addr_from = form_data[b'addr_from'][0].decode('utf-8')
@ -394,6 +400,7 @@ class HttpHandler(BaseHTTPRequestHandler):
'created_at': offer.created_at,
'expired_at': offer.expire_at,
'sent': 'True' if offer.was_sent else 'False',
'was_revoked': 'True' if offer.active_ind == 2 else 'False',
'show_bid_form': show_bid_form,
}

View file

@ -64,8 +64,6 @@ from .contrib.test_framework.script import (
SegwitV0SignatureHash,
hash160)
from .contrib.test_framework.key import ECKey, ECPubKey
from .chainparams import CoinInterface, Coins, chainparams
from .rpc import make_rpc_func
from .util import assert_cond
@ -642,14 +640,11 @@ class BTCInterface(CoinInterface):
return True
def signTx(self, key_bytes, tx_bytes, prevout_n, prevout_script, prevout_value):
# TODO: use libsecp356k1
tx = self.loadTx(tx_bytes)
sig_hash = SegwitV0SignatureHash(prevout_script, tx, prevout_n, SIGHASH_ALL, prevout_value)
eck = ECKey()
eck.set(key_bytes, compressed=True)
return eck.sign_ecdsa(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL
eck = PrivateKey(key_bytes)
return eck.sign(sig_hash, hasher=None) + bytes((SIGHASH_ALL,))
def signTxOtVES(self, key_sign, pubkey_encrypt, tx_bytes, prevout_n, prevout_script, prevout_value):
tx = self.loadTx(tx_bytes)
@ -663,20 +658,18 @@ class BTCInterface(CoinInterface):
return ecdsaotves_enc_verify(Ks, Ke, sig_hash, ct)
def decryptOtVES(self, k, esig):
return ecdsaotves_dec_sig(k, esig) + b'\x01' # 0x1 is SIGHASH_ALL
return ecdsaotves_dec_sig(k, esig) + bytes((SIGHASH_ALL,))
def verifyTxSig(self, tx_bytes, sig, K, prevout_n, prevout_script, prevout_value):
tx = self.loadTx(tx_bytes)
sig_hash = SegwitV0SignatureHash(prevout_script, tx, prevout_n, SIGHASH_ALL, prevout_value)
ecK = ECPubKey()
ecK.set(K)
return ecK.verify_ecdsa(sig[: -1], sig_hash) # Pop the hashtype byte
pubkey = PublicKey(K)
return pubkey.verify(sig[: -1], sig_hash, hasher=None) # Pop the hashtype byte
def verifySig(self, pubkey, signed_hash, sig):
ecK = ECPubKey()
ecK.set(pubkey)
return ecK.verify_ecdsa(sig, signed_hash)
pubkey = PublicKey(pubkey)
return pubkey.verify(sig, signed_hash, hasher=None)
def fundTx(self, tx, feerate):
feerate_str = format_amount(feerate, self.exp())

View file

@ -9,13 +9,34 @@
TODO:
'''
import select
import socket
import logging
class Peer:
pass
class Network:
def __init__(self, p2p_port, network_key):
def __init__(self, p2p_host, p2p_port, network_key):
self._p2p_host = p2p_host
self._p2p_port = p2p_port
self._network_key = network_key
self._peers = []
self._max_connections = 10
self._running = True
def listen(self):
self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self._socket.bind((self._p2p_host, self._p2p_port))
self._socket.listen(self._max_connections)
while self._running:
readable, writable, errored = select.select([self._socket], [], [])
for s in readable:
client_socket, address = self._socket.accept()
read_list.append(client_socket)
logging.info('Connection from %s', address)

View file

@ -53,7 +53,7 @@
{% if data.was_received == 'True' %}
<input name="accept_bid" type="submit" value="Accept Bid"><br/>
{% endif %}
<input name="abandon_bid" type="submit" value="Abandon Bid">
<input name="abandon_bid" type="submit" value="Abandon Bid" onclick="confirmPopup()">
{% if data.show_txns %}
<input name="hide_txns" type="submit" value="Hide Info">
{% else %}
@ -74,4 +74,10 @@
</table>
<p><a href="/">home</a></p>
<script>
function confirmPopup() {
confirm("Are you sure?");
}
</script>
</body></html>

View file

@ -26,6 +26,7 @@
<tr><td>Created At</td><td>{{ data.created_at | formatts }}</td></tr>
<tr><td>Expired At</td><td>{{ data.expired_at | formatts }}</td></tr>
<tr><td>Sent</td><td>{{ data.sent }}</td></tr>
<tr><td>Revoked</td><td>{{ data.was_revoked }}</td></tr>
{% if data.sent == 'True' %}
<tr><td>Auto Accept Bids</td><td>{{ data.auto_accept }}</td></tr>
{% endif %}
@ -56,6 +57,9 @@
{% else %}
<input type="submit" name="newbid" value="New Bid">
{% endif %}
{% if data.sent == 'True' %}
<input name="revoke_offer" type="submit" value="Revoke Offer" onclick="confirmPopup()">
{% endif %}
<input type="hidden" name="formid" value="{{ form_id }}">
</form>
@ -69,4 +73,10 @@
</table>
<p><a href="/">home</a></p>
<script>
function confirmPopup() {
confirm("Are you sure?");
}
</script>
</body></html>

View file

@ -6,37 +6,36 @@
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
import secrets
import hashlib
import unittest
import basicswap.contrib.ed25519_fast as edf
import basicswap.ed25519_fast_util as edu
from basicswap.ecc_util import i2b
from coincurve.ed25519 import ed25519_get_pubkey
from coincurve.ecdsaotves import (
ecdsaotves_enc_sign,
ecdsaotves_enc_verify,
ecdsaotves_dec_sig,
ecdsaotves_rec_enc_key)
from coincurve.keys import (
PrivateKey)
from basicswap.ecc_util import i2b
from basicswap.interface_btc import BTCInterface
from basicswap.interface_xmr import XMRInterface
from basicswap.util import (
SerialiseNum,
DeserialiseNum,
make_int,
format_amount,
validate_amount,
)
validate_amount)
from basicswap.basicswap import (
Coins,
getExpectedSequence,
decodeSequence,
SEQUENCE_LOCK_BLOCKS,
SEQUENCE_LOCK_TIME,
)
SEQUENCE_LOCK_TIME)
class Test(unittest.TestCase):
@ -182,6 +181,20 @@ class Test(unittest.TestCase):
assert(vk_encrypt == recovered_key)
def test_sign(self):
coin_settings = {'rpcport': 0, 'rpcauth': 'none', 'blocks_confirmed': 1, 'conf_target': 1}
ci = BTCInterface(coin_settings, 'regtest')
vk = i2b(ci.getNewSecretKey())
pk = ci.getPubkey(vk)
message = 'test signing message'
message_hash = hashlib.sha256(bytes(message, 'utf-8')).digest()
eck = PrivateKey(vk)
sig = eck.sign(message.encode('utf-8'))
ci.verifySig(pk, message_hash, sig)
def test_sign_compact(self):
coin_settings = {'rpcport': 0, 'rpcauth': 'none', 'blocks_confirmed': 1, 'conf_target': 1}
ci = BTCInterface(coin_settings, 'regtest')
@ -192,6 +205,7 @@ class Test(unittest.TestCase):
assert(len(sig) == 64)
ci.verifyCompact(pk, 'test signing message', sig)
def test_dleag(self):
coin_settings = {'rpcport': 0, 'walletrpcport': 0, 'walletrpcauth': 'none', 'blocks_confirmed': 1, 'conf_target': 1}
ci = XMRInterface(coin_settings, 'regtest')