acvm/pwg/blackbox/signature/
ecdsa.rs

1use acir::{
2    AcirField,
3    circuit::opcodes::FunctionInput,
4    native_types::{Witness, WitnessMap},
5};
6use acvm_blackbox_solver::{ecdsa_secp256k1_verify, ecdsa_secp256r1_verify};
7
8use crate::{
9    OpcodeResolutionError,
10    pwg::{blackbox::utils::to_u8_array, input_to_value, insert_value},
11};
12
13pub(crate) fn secp256k1_prehashed<F: AcirField>(
14    initial_witness: &mut WitnessMap<F>,
15    public_key_x_inputs: &[FunctionInput<F>; 32],
16    public_key_y_inputs: &[FunctionInput<F>; 32],
17    signature_inputs: &[FunctionInput<F>; 64],
18    hashed_message_inputs: &[FunctionInput<F>; 32],
19    predicate: &FunctionInput<F>,
20    output: Witness,
21) -> Result<(), OpcodeResolutionError<F>> {
22    let is_valid = execute_ecdsa(
23        initial_witness,
24        public_key_x_inputs,
25        public_key_y_inputs,
26        signature_inputs,
27        hashed_message_inputs,
28        predicate,
29        true,
30    )?;
31    insert_value(&output, F::from(is_valid), initial_witness)
32}
33
34pub(crate) fn execute_ecdsa<F: AcirField>(
35    initial_witness: &WitnessMap<F>,
36    public_key_x_inputs: &[FunctionInput<F>; 32],
37    public_key_y_inputs: &[FunctionInput<F>; 32],
38    signature_inputs: &[FunctionInput<F>; 64],
39    hashed_message_inputs: &[FunctionInput<F>; 32],
40    predicate: &FunctionInput<F>,
41    k1: bool,
42) -> Result<bool, OpcodeResolutionError<F>> {
43    let pub_key_x: [u8; 32] = to_u8_array(initial_witness, public_key_x_inputs)?;
44    let pub_key_y: [u8; 32] = to_u8_array(initial_witness, public_key_y_inputs)?;
45    let signature: [u8; 64] = to_u8_array(initial_witness, signature_inputs)?;
46    let hashed_message: [u8; 32] = to_u8_array(initial_witness, hashed_message_inputs)?;
47    let predicate = input_to_value(initial_witness, *predicate)?.is_one();
48    let is_valid = if predicate {
49        if k1 {
50            ecdsa_secp256k1_verify(&hashed_message, &pub_key_x, &pub_key_y, &signature)?
51        } else {
52            ecdsa_secp256r1_verify(&hashed_message, &pub_key_x, &pub_key_y, &signature)?
53        }
54    } else {
55        true
56    };
57
58    Ok(is_valid)
59}
60
61pub(crate) fn secp256r1_prehashed<F: AcirField>(
62    initial_witness: &mut WitnessMap<F>,
63    public_key_x_inputs: &[FunctionInput<F>; 32],
64    public_key_y_inputs: &[FunctionInput<F>; 32],
65    signature_inputs: &[FunctionInput<F>; 64],
66    hashed_message_inputs: &[FunctionInput<F>; 32],
67    predicate: &FunctionInput<F>,
68    output: Witness,
69) -> Result<(), OpcodeResolutionError<F>> {
70    let is_valid = execute_ecdsa(
71        initial_witness,
72        public_key_x_inputs,
73        public_key_y_inputs,
74        signature_inputs,
75        hashed_message_inputs,
76        predicate,
77        false,
78    )?;
79    insert_value(&output, F::from(is_valid), initial_witness)
80}