add missing code for inputs

This commit is contained in:
narodnik
2022-05-06 22:46:01 +02:00
parent 0ba4ad95fe
commit 70293fd181
2 changed files with 112 additions and 4 deletions

View File

@@ -20,7 +20,11 @@ class TransactionBuilder:
clear_input.signature_secret = signature_secret
self.clear_inputs.append(clear_input)
def add_input(self, input):
def add_input(self, all_coins, secret, note):
input = ClassNamespace()
input.all_coins = all_coins
input.secret = secret
input.note = note
self.inputs.append(input)
def add_output(self, value, token_id, public):
@@ -54,8 +58,21 @@ class TransactionBuilder:
tx.clear_inputs.append(tx_clear_input)
input_blinds = []
signature_secrets = []
for input in self.inputs:
# FIXME: BUG - see corresponding builder.rs file
input_blinds.append(input.note.value_blind)
signature_secret = self.ec.random_scalar()
signature_secrets.append(signature_secret)
tx_input = ClassNamespace()
tx_input.__name__ = "TransactionInput"
tx_input.burn_proof = BurnProof(
input.note.value, input.note.token_id, input.note.value_blind,
token_blind, input.note.serial, input.note.coin_blind,
input.secret, input.all_coins, signature_secret, self.ec)
tx_input.revealed = tx_input.burn_proof.get_revealed()
tx.inputs.append(tx_input)
assert self.outputs
@@ -97,13 +114,71 @@ class TransactionBuilder:
secret = info.signature_secret
signature = sign(unsigned_tx_data, secret, self.ec)
input.signature = signature
for (input, info) in zip(tx.inputs, self.inputs):
secret = info.signature_secret
signature = sign(unsigned_tx_data, secret, self.ec)
for (input, signature_secret) in zip(tx.inputs, signature_secrets):
signature = sign(unsigned_tx_data, signature_secret, self.ec)
input.signature = signature
return tx
class BurnProof:
def __init__(self, value, token_id, value_blind, token_blind, serial,
coin_blind, secret, all_coins, signature_secret, ec):
self.value = value
self.token_id = token_id
self.value_blind = value_blind
self.token_blind = token_blind
self.serial = serial
self.coin_blind = coin_blind
self.secret = secret
self.all_coins = all_coins
self.signature_secret = signature_secret
self.ec = ec
def get_revealed(self):
revealed = ClassNamespace()
revealed.nullifier = ff_hash(self.secret, self.serial)
revealed.value_commit = pedersen_encrypt(
self.value, self.value_blind, self.ec
)
revealed.token_commit = pedersen_encrypt(
self.token_id, self.token_blind, self.ec
)
revealed.all_coins = self.all_coins
revealed.signature_public = self.ec.multiply(self.signature_secret,
self.ec.G)
return revealed
def verify(self, public):
revealed = self.get_revealed()
public_key = self.ec.multiply(self.secret, self.ec.G)
coin = ff_hash(
self.ec.p,
public_key[0],
public_key[1],
self.value,
self.token_id,
self.serial,
self.coin_blind
)
# Merkle root check
if coin not in self.all_coins:
return False
return all([
revealed.nullifier == public.nullifier,
revealed.value_commit == public.value_commit,
revealed.token_commit == public.token_commit,
revealed.all_coins == public.all_coins,
revealed.signature_public == public.signature_public
])
class MintProof:
def __init__(self, value, token_id, value_blind, token_blind, serial,
@@ -289,6 +364,37 @@ def main(argv):
print(f"tx verify failed: {reason}", file=sys.stderr)
return -1
assert len(tx.outputs) > 0
note = tx.outputs[0].enc_note
coin = ff_hash(
ec.p,
public[0],
public[1],
note.value,
note.token_id,
note.serial,
note.coin_blind
)
assert coin == tx.outputs[0].mint_proof.get_revealed().coin
all_coins = [coin]
builder = TransactionBuilder(ec)
builder.add_input(all_coins, secret, note)
secret2 = ec.random_scalar()
public2 = ec.multiply(secret, ec.G)
builder.add_output(1000, token_id, public2)
# Change
builder.add_output(note.value - 1000, token_id, public)
tx = builder.build()
is_verify, reason = tx.verify()
if not is_verify:
print(f"tx2 verify failed: {reason}", file=sys.stderr)
return -1
return 0
if __name__ == "__main__":

View File

@@ -89,6 +89,8 @@ impl TransactionBuilder {
let mut input_blinds = vec![];
let mut signature_secrets = vec![];
for input in self.inputs {
// FIXME: BUG - looks like we are reusing the value_blind from the output
// This must be a completely new random value or the value_commit will be the same.
input_blinds.push(input.note.value_blind);
let signature_secret = SecretKey::random(&mut OsRng);