1use crate::{hashing::blake2b_224, register::Register};
2use blstrs::{G1Affine, G1Projective, Scalar};
3
4use ff::Field;
5use hex;
6use rand_core::OsRng;
7
8pub fn fiat_shamir_heuristic(g_b: String, g_r_b: String, u_b: String, b: String) -> String {
24 let concatenated: String = format!("{}{}{}{}", g_b, g_r_b, u_b, b);
26
27 blake2b_224(&concatenated)
29}
30
31pub fn random_scalar() -> Scalar {
40 Scalar::random(&mut OsRng)
41}
42
43pub fn create_proof(datum: Register, sk: Scalar, bound: String) -> (String, String) {
61 let r: Scalar = random_scalar();
62 let g1: G1Affine = G1Affine::from_compressed(
63 &hex::decode(&datum.generator)
64 .expect("Failed to decode generator hex")
65 .try_into()
66 .expect("Invalid generator length"),
67 )
68 .expect("Failed to decompress generator");
69
70 let g_r: G1Projective = G1Projective::from(g1) * r;
71
72 let c_hex: String = fiat_shamir_heuristic(
73 datum.generator,
74 hex::encode(g_r.to_compressed()),
75 datum.public_value,
76 bound,
77 );
78 let c_bytes: Vec<u8> = hex::decode(&c_hex).expect("Failed to decode Fiat-Shamir output");
79 let mut c_array: [u8; 32] = [0u8; 32];
80 c_array[(32 - c_bytes.len())..].copy_from_slice(&c_bytes);
81 let c: Scalar = Scalar::from_bytes_be(&c_array).unwrap();
82
83 let z: Scalar = r + c * sk;
84 (
85 hex::encode(z.to_bytes_be()),
86 hex::encode(g_r.to_compressed()),
87 )
88}
89
90pub fn prove(generator: &str, public_value: &str, z_b: &str, g_r_b: &str, bound: &str) -> bool {
92 let g1: G1Affine = G1Affine::from_compressed(
94 &hex::decode(generator)
95 .expect("Failed to decode generator hex")
96 .try_into()
97 .expect("Invalid generator length"),
98 )
99 .expect("Failed to decompress generator");
100
101 let u: G1Affine = G1Affine::from_compressed(
103 &hex::decode(public_value)
104 .expect("Failed to decode public value hex")
105 .try_into()
106 .expect("Invalid public value length"),
107 )
108 .expect("Failed to decompress public value");
109
110 let g_r: G1Affine = G1Affine::from_compressed(
112 &hex::decode(g_r_b)
113 .expect("Failed to decode g_r_b hex")
114 .try_into()
115 .expect("Invalid g_r_b length"),
116 )
117 .expect("Failed to decompress g_r_b");
118
119 let z_bytes: Vec<u8> = hex::decode(z_b).expect("Failed to decode z_b hex");
121 let mut z_array: [u8; 32] = [0u8; 32];
122 z_array[(32 - z_bytes.len())..].copy_from_slice(&z_bytes);
123 let z: Scalar = Scalar::from_bytes_be(&z_array).unwrap();
124
125 let g_z: G1Projective = g1 * z; let c_hex: String = fiat_shamir_heuristic(
130 generator.to_string(),
131 g_r_b.to_string(),
132 public_value.to_string(),
133 bound.to_string(),
134 );
135 let c_bytes: Vec<u8> = hex::decode(&c_hex).expect("Failed to decode Fiat-Shamir output");
136 let mut c_array = [0u8; 32];
137 c_array[(32 - c_bytes.len())..].copy_from_slice(&c_bytes);
138 let c = Scalar::from_bytes_be(&c_array).unwrap();
139
140 let u_c: G1Projective = u * c;
142
143 g_z == (G1Projective::from(g_r) + u_c)
145}