sign with sighash/signature prompts

This commit is contained in:
Conrado Gouvea 2023-05-29 11:51:38 -03:00
parent c36c311c01
commit cce162bc89
6 changed files with 33 additions and 10 deletions

View File

@ -637,7 +637,7 @@ pub async unsafe extern "C" fn sign(
from_c_str!(tx_plan);
let res = async {
let tx_plan: TransactionPlan = serde_json::from_str(&tx_plan)?;
let raw_tx = crate::api::payment_v2::sign_plan(coin, account, &tx_plan)?;
let raw_tx = crate::api::payment_v2::sign_plan(coin, account, &tx_plan, false)?;
let tx_str = base64::encode(&raw_tx);
Ok::<_, anyhow::Error>(tx_str)
};

View File

@ -122,7 +122,7 @@ pub async fn build_tx_plan(
Ok(tx_plan)
}
pub fn sign_plan(coin: u8, account: u32, tx_plan: &TransactionPlan) -> anyhow::Result<Vec<u8>> {
pub fn sign_plan(coin: u8, account: u32, tx_plan: &TransactionPlan, frost: bool) -> anyhow::Result<Vec<u8>> {
let c = CoinConfig::get(coin);
let network = c.chain.network();
let fvk = {
@ -146,7 +146,7 @@ pub fn sign_plan(coin: u8, account: u32, tx_plan: &TransactionPlan) -> anyhow::R
}
let keys = get_secret_keys(coin, account)?;
let tx = build_tx(c.chain.network(), &keys, &tx_plan, OsRng)?;
let tx = build_tx(c.chain.network(), &keys, &tx_plan, frost, OsRng)?;
Ok(tx)
}
@ -155,7 +155,7 @@ pub async fn sign_and_broadcast(
account: u32,
tx_plan: &TransactionPlan,
) -> anyhow::Result<String> {
let tx = sign_plan(coin, account, tx_plan)?;
let tx = sign_plan(coin, account, tx_plan, false)?;
let txid = broadcast_tx(&tx).await?;
let id_notes: Vec<_> = tx_plan
.spends

View File

@ -349,7 +349,7 @@ pub async fn build_from_plan(tx_plan: Json<TransactionPlan>) -> Result<String, E
}
let keys = get_secret_keys(c.coin, c.id_account)?;
let tx = build_tx(c.chain.network(), &keys, &tx_plan, OsRng).unwrap();
let tx = build_tx(c.chain.network(), &keys, &tx_plan, false, OsRng).unwrap();
let tx = hex::encode(&tx);
Ok(tx)
}

View File

@ -88,7 +88,7 @@ fn main() -> anyhow::Result<()> {
orchard: orchard_sk,
};
let tx = build_tx(&network, &keys, &tx_plan, OsRng)?;
let tx = build_tx(&network, &keys, &tx_plan, true, OsRng)?;
fs::write(out_filename, hex::encode(&tx))?;
Ok(())

View File

@ -11,6 +11,7 @@ use orchard::builder::Builder as OrchardBuilder;
use orchard::bundle::Flags;
use orchard::keys::{FullViewingKey, Scope, SpendAuthorizingKey, SpendingKey};
use orchard::note::Nullifier;
use orchard::primitives::redpallas::{self, SpendAuth};
use orchard::value::NoteValue;
use orchard::{Address, Anchor, Bundle};
use rand::{CryptoRng, RngCore};
@ -72,6 +73,7 @@ pub fn build_tx(
network: &Network,
skeys: &SecretKeys,
plan: &TransactionPlan,
frost: bool,
mut rng: impl RngCore + CryptoRng + Clone,
) -> anyhow::Result<Vec<u8>> {
let secp = Secp256k1::<All>::new();
@ -251,6 +253,10 @@ pub fn build_tx(
let sig_hash = signature_hash(&unauthed_tx, &SignableInput::Shielded, &txid_parts);
let sig_hash: [u8; 32] = sig_hash.as_ref().clone();
if frost {
println!("SIGHASH: {}", hex::encode(&sig_hash));
}
let transparent_bundle = unauthed_tx
.transparent_bundle()
.map(|tb| tb.clone().apply_signatures(&unauthed_tx, &txid_parts));
@ -272,9 +278,26 @@ pub fn build_tx(
.clone()
.create_proof(get_proving_key(), &mut rng)
.unwrap();
proven
.apply_signatures(&mut rng, sig_hash, &orchard_signing_keys)
.unwrap()
if frost {
let mut buffer = String::new();
let stdin = std::io::stdin();
println!("Input hex-encoded signature: ");
stdin.read_line(&mut buffer).unwrap();
let signature = hex::decode(buffer.trim()).unwrap();
let signature: [u8; 64] = signature.try_into().unwrap();
let signature = redpallas::Signature::<SpendAuth>::from(signature);
proven
.prepare(&mut rng, sig_hash)
.append_signatures(&[signature])
.unwrap()
.finalize()
.unwrap()
} else {
proven
.apply_signatures(&mut rng, sig_hash, &orchard_signing_keys)
.unwrap()
}
});
let tx_data: TransactionData<zcash_primitives::transaction::Authorized> =

View File

@ -353,7 +353,7 @@ pub async fn sweep_tkey(
orchard: None,
};
println!("build_tx");
let tx = build_tx(network, &skeys, &tx_plan, OsRng)?;
let tx = build_tx(network, &skeys, &tx_plan, false, OsRng)?;
println!("broadcast_tx");
let txid = broadcast_tx(&tx).await?;
Ok(txid)