signedby_sdk/
verification_key.rs1use ark_bn254::{Bn254, Fq, Fq2, G1Affine, G2Affine};
8use ark_groth16::VerifyingKey;
9use ark_serialize::CanonicalDeserialize;
10use serde::{Deserialize, Serialize};
11
12use crate::error::SdkError;
13
14#[derive(Clone)]
16pub struct VerificationKey {
17 pub(crate) inner: VerifyingKey<Bn254>,
19}
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct VerificationKeyJson {
24 pub protocol: String,
25 pub curve: String,
26 #[serde(rename = "nPublic")]
27 pub n_public: usize,
28 pub vk_alpha_1: Vec<String>,
29 pub vk_beta_2: Vec<Vec<String>>,
30 pub vk_gamma_2: Vec<Vec<String>>,
31 pub vk_delta_2: Vec<Vec<String>>,
32 #[serde(rename = "vk_alphabeta_12")]
33 pub vk_alphabeta_12: Option<Vec<Vec<Vec<String>>>>,
34 #[serde(rename = "IC")]
35 pub ic: Vec<Vec<String>>,
36}
37
38impl VerificationKey {
39 pub fn from_json(json: &str) -> Result<Self, SdkError> {
41 let vk_json: VerificationKeyJson = serde_json::from_str(json)?;
42 Self::from_snarkjs(&vk_json)
43 }
44
45 pub fn from_snarkjs(vk_json: &VerificationKeyJson) -> Result<Self, SdkError> {
47 let alpha_g1 = parse_g1(&vk_json.vk_alpha_1)?;
49
50 let beta_g2 = parse_g2(&vk_json.vk_beta_2)?;
52
53 let gamma_g2 = parse_g2(&vk_json.vk_gamma_2)?;
55
56 let delta_g2 = parse_g2(&vk_json.vk_delta_2)?;
58
59 let gamma_abc_g1: Vec<G1Affine> = vk_json.ic
61 .iter()
62 .map(|p| parse_g1(p))
63 .collect::<Result<Vec<_>, _>>()?;
64
65 let inner = VerifyingKey {
66 alpha_g1,
67 beta_g2,
68 gamma_g2,
69 delta_g2,
70 gamma_abc_g1,
71 };
72
73 Ok(Self { inner })
74 }
75
76 pub fn from_bytes(bytes: &[u8]) -> Result<Self, SdkError> {
78 let inner = VerifyingKey::<Bn254>::deserialize_uncompressed(bytes)
79 .map_err(|e| SdkError::InvalidVerificationKey(format!("Deserialize failed: {:?}", e)))?;
80 Ok(Self { inner })
81 }
82
83 pub fn num_public_inputs(&self) -> usize {
85 self.inner.gamma_abc_g1.len() - 1
86 }
87}
88
89fn parse_g1(coords: &[String]) -> Result<G1Affine, SdkError> {
91 if coords.len() < 2 {
92 return Err(SdkError::InvalidVerificationKey("G1 needs at least 2 coordinates".into()));
93 }
94
95 let x = parse_fq(&coords[0])?;
96 let y = parse_fq(&coords[1])?;
97
98 Ok(G1Affine::new(x, y))
99}
100
101fn parse_g2(coords: &[Vec<String>]) -> Result<G2Affine, SdkError> {
103 if coords.len() < 2 {
104 return Err(SdkError::InvalidVerificationKey("G2 needs at least 2 coordinate pairs".into()));
105 }
106
107 let x = Fq2::new(parse_fq(&coords[0][0])?, parse_fq(&coords[0][1])?);
108 let y = Fq2::new(parse_fq(&coords[1][0])?, parse_fq(&coords[1][1])?);
109
110 Ok(G2Affine::new(x, y))
111}
112
113fn parse_fq(s: &str) -> Result<Fq, SdkError> {
115 use ark_ff::PrimeField;
116 use num_bigint::BigUint;
117 use std::str::FromStr;
118
119 let n = BigUint::from_str(s)
120 .map_err(|e| SdkError::InvalidVerificationKey(format!("Invalid field element: {}", e)))?;
121
122 let bytes = n.to_bytes_le();
123 let mut padded = [0u8; 32];
124 let len = bytes.len().min(32);
125 padded[..len].copy_from_slice(&bytes[..len]);
126
127 Ok(Fq::from_le_bytes_mod_order(&padded))
128}
129
130#[cfg(test)]
131mod tests {
132 use super::*;
133
134 #[test]
135 fn test_parse_fq() {
136 let result = parse_fq("123456789");
137 assert!(result.is_ok());
138 }
139}