improve unblinding

This commit is contained in:
Stepan Snigirev 2021-10-01 19:43:52 +02:00
parent b2f98d8bfc
commit 567903b018
3 changed files with 23 additions and 10 deletions

View File

@ -9,7 +9,7 @@ from .. import compact, hashes
from ..psbt import *
from collections import OrderedDict
from io import BytesIO
from .transaction import LTransaction, LTransactionOutput, LTransactionInput, TxOutWitness, Proof, LSIGHASH, unblind
from .transaction import LTransaction, LTransactionOutput, LTransactionInput, TxOutWitness, Proof, RangeProof, LSIGHASH, unblind
from . import slip77
import hashlib, gc
@ -40,10 +40,13 @@ class LInputScope(InputScope):
return
pk = slip77.blinding_key(blinding_key, self.utxo.script_pubkey)
value, asset, vbf, in_abf, extra, min_value, max_value = unblind(
self.utxo.ecdh_pubkey, pk.secret, self.range_proof, self.utxo.value, self.utxo.asset, self.utxo.script_pubkey
)
try:
value, asset, vbf, in_abf, extra, min_value, max_value = unblind(
self.utxo.ecdh_pubkey, pk.secret, self.range_proof, self.utxo.value, self.utxo.asset, self.utxo.script_pubkey
)
# failed to unblind
except:
return
# verify
gen = secp256k1.generator_generate_blinded(asset, in_abf)
assert gen == secp256k1.generator_parse(self.utxo.asset)
@ -169,7 +172,7 @@ class LOutputScope(OutputScope):
def vout(self):
return LTransactionOutput(
self.asset or self.asset_commitment,
self.value or self.value_commitment,
self.value if self.value is not None else self.value_commitment,
self.script_pubkey,
None if self.asset else self.ecdh_pubkey)
@ -180,7 +183,7 @@ class LOutputScope(OutputScope):
self.value_commitment or self.value,
self.script_pubkey,
self.ecdh_pubkey,
None if not self.surjection_proof else TxOutWitness(Proof(self.surjection_proof), Proof(self.range_proof))
None if not self.surjection_proof else TxOutWitness(Proof(self.surjection_proof), RangeProof(self.range_proof))
)
def reblind(self, nonce, blinding_pubkey=None, extra_message=b""):
@ -345,7 +348,7 @@ class PSET(PSBT):
abfs = []
vbfs = []
for sc in self.inputs + blinding_outs:
value = sc.value or sc.utxo.value
value = sc.value if sc.value is not None else sc.utxo.value
asset = sc.asset or sc.utxo.asset
if not (isinstance(value, int) and len(asset) == 32):
continue

View File

@ -98,6 +98,14 @@ class Proof(EmbitBase):
return cls(data)
class RangeProof(Proof):
def unblind(self, ecdh_pubkey, blinding_key, value, asset, script_pubkey, message_length=64):
if not self.data:
raise TransactionError("Rangeproof is empty")
return unblind(ecdh_pubkey, blinding_key, self.data, value, asset, script_pubkey, message_length)
class TxInWitness(EmbitBase):
def __init__(self, amount_proof=None, token_proof=None, script_witness=None, pegin_witness=None):
self.amount_proof = amount_proof if amount_proof is not None else Proof()
@ -123,7 +131,7 @@ class TxInWitness(EmbitBase):
class TxOutWitness(EmbitBase):
def __init__(self, surjection_proof=None, range_proof=None):
self.surjection_proof = surjection_proof if surjection_proof is not None else Proof()
self.range_proof = range_proof if range_proof is not None else Proof()
self.range_proof = range_proof if range_proof is not None else RangeProof()
def write_to(self, stream):
res = self.surjection_proof.write_to(stream)
@ -136,7 +144,7 @@ class TxOutWitness(EmbitBase):
@classmethod
def read_from(cls, stream):
return cls(Proof.read_from(stream), Proof.read_from(stream))
return cls(Proof.read_from(stream), RangeProof.read_from(stream))
class LTransaction(Transaction):

View File

@ -856,6 +856,8 @@ def rangeproof_rewind(proof, nonce, value_commitment, script_pubkey, generator,
@locked
def rangeproof_sign(nonce, value, value_commitment, vbf, message, extra, gen, min_value=1, exp=0, min_bits=52, context=_secp.ctx):
if value == 0:
min_value = 0
if len(gen)!=64:
raise ValueError("Generator should be 64 bytes long")
if len(nonce)!=32: