mina_tree/scan_state/transaction_logic/
verifiable.rs

1use std::ops::Neg;
2
3use ark_ff::{BigInteger, PrimeField};
4use mina_signer::CompressedPubKey;
5
6use super::{
7    signed_command, transaction_union_payload::TransactionUnionPayload, valid, zkapp_command,
8};
9
10#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
11pub enum UserCommand {
12    SignedCommand(Box<signed_command::SignedCommand>),
13    ZkAppCommand(Box<zkapp_command::verifiable::ZkAppCommand>),
14}
15
16pub fn compressed_to_pubkey(pubkey: &CompressedPubKey) -> mina_signer::PubKey {
17    // Taken from https://github.com/o1-labs/proof-systems/blob/e3fc04ce87f8695288de167115dea80050ab33f4/signer/src/pubkey.rs#L95-L106
18    let mut pt =
19        mina_signer::CurvePoint::get_point_from_x_unchecked(pubkey.x, pubkey.is_odd).unwrap();
20
21    if pt.y.into_bigint().is_even() == pubkey.is_odd {
22        pt.y = pt.y.neg();
23    }
24
25    assert!(pt.is_on_curve());
26
27    // Safe now because we checked point pt is on curve
28    mina_signer::PubKey::from_point_unsafe(pt)
29}
30
31/// <https://github.com/MinaProtocol/mina/blob/05c2f73d0f6e4f1341286843814ce02dcb3919e0/src/lib/mina_base/signed_command.ml#L436>
32pub fn check_only_for_signature(
33    cmd: Box<signed_command::SignedCommand>,
34) -> Result<valid::UserCommand, Box<signed_command::SignedCommand>> {
35    // <https://github.com/MinaProtocol/mina/blob/05c2f73d0f6e4f1341286843814ce02dcb3919e0/src/lib/mina_base/signed_command.ml#L396>
36
37    let signed_command::SignedCommand {
38        payload,
39        signer: pubkey,
40        signature,
41    } = &*cmd;
42
43    let payload = TransactionUnionPayload::of_user_command_payload(payload);
44    let pubkey = compressed_to_pubkey(pubkey);
45
46    if crate::verifier::common::legacy_verify_signature(signature, &pubkey, &payload) {
47        Ok(valid::UserCommand::SignedCommand(cmd))
48    } else {
49        Err(cmd)
50    }
51}