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] bids_received += r[2]
now = int(time.time()) 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] num_offers = q[0]
q = self.engine.execute('SELECT COUNT(*) FROM offers WHERE was_sent = 1').first() 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 show_bid_form = None
form_data = self.checkForm(post_string, 'offer', messages) form_data = self.checkForm(post_string, 'offer', messages)
if form_data: 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 show_bid_form = True
else: else:
addr_from = form_data[b'addr_from'][0].decode('utf-8') addr_from = form_data[b'addr_from'][0].decode('utf-8')
@ -394,6 +400,7 @@ class HttpHandler(BaseHTTPRequestHandler):
'created_at': offer.created_at, 'created_at': offer.created_at,
'expired_at': offer.expire_at, 'expired_at': offer.expire_at,
'sent': 'True' if offer.was_sent else 'False', 'sent': 'True' if offer.was_sent else 'False',
'was_revoked': 'True' if offer.active_ind == 2 else 'False',
'show_bid_form': show_bid_form, 'show_bid_form': show_bid_form,
} }

View File

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

View File

@ -9,13 +9,34 @@
TODO: TODO:
''' '''
import select
import socket
import logging
class Peer: class Peer:
pass pass
class Network: 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._p2p_port = p2p_port
self._network_key = network_key self._network_key = network_key
self._peers = [] 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' %} {% if data.was_received == 'True' %}
<input name="accept_bid" type="submit" value="Accept Bid"><br/> <input name="accept_bid" type="submit" value="Accept Bid"><br/>
{% endif %} {% 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 %} {% if data.show_txns %}
<input name="hide_txns" type="submit" value="Hide Info"> <input name="hide_txns" type="submit" value="Hide Info">
{% else %} {% else %}
@ -74,4 +74,10 @@
</table> </table>
<p><a href="/">home</a></p> <p><a href="/">home</a></p>
<script>
function confirmPopup() {
confirm("Are you sure?");
}
</script>
</body></html> </body></html>

View File

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

View File

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