blueprint_crypto_bn254/
lib.rs1#![cfg_attr(not(feature = "std"), no_std)]
2
3pub mod aggregation;
4pub mod error;
5use error::{Bn254Error, Result};
6
7#[cfg(test)]
8mod tests;
9
10use ark_bn254::{Bn254, Fq, Fr, G1Affine, G1Projective, G2Affine};
11use ark_ec::{AffineRepr, CurveGroup, pairing::Pairing};
12#[cfg(feature = "std")]
13use ark_ff::UniformRand;
14use ark_ff::{BigInteger256, Field, One, PrimeField};
15use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
16use blueprint_crypto_core::BytesEncoding;
17use blueprint_crypto_core::{KeyType, KeyTypeId};
18use blueprint_std::hash::Hash;
19use blueprint_std::vec::Vec;
20use blueprint_std::{
21 str::FromStr,
22 string::{String, ToString},
23};
24use num_bigint::BigUint;
25use serde::{Deserialize, Serialize};
26use sha2::{Digest, Sha256};
27
28pub fn to_bytes<T: CanonicalSerialize>(elt: T) -> Vec<u8> {
30 let mut bytes = Vec::with_capacity(elt.compressed_size());
31
32 <T as CanonicalSerialize>::serialize_compressed(&elt, &mut bytes).unwrap();
33
34 bytes
35}
36
37pub fn from_bytes<T: CanonicalDeserialize>(bytes: &[u8]) -> T {
39 <T as CanonicalDeserialize>::deserialize_compressed(&mut &bytes[..]).unwrap()
40}
41
42fn hash_to_curve(digest: &[u8]) -> G1Affine {
43 let one = Fq::one();
44 let three = Fq::from(3u64);
45
46 let mut hasher = Sha256::new();
47 hasher.update(digest);
48 let hashed_result = hasher.finalize();
49
50 let mut x = {
52 let big_int = BigUint::from_bytes_be(&hashed_result);
53 let mut bytes = [0u8; 32];
54 big_int
55 .to_bytes_be()
56 .iter()
57 .rev()
58 .enumerate()
59 .for_each(|(i, &b)| bytes[i] = b);
60 Fq::from_le_bytes_mod_order(&bytes)
61 };
62
63 loop {
64 let mut y = x;
66 y.square_in_place();
67 y *= x;
68 y += three;
69
70 if let Some(y) = y.sqrt() {
72 return G1Projective::new(x, y, Fq::one()).into_affine();
73 }
74 x += one;
76 }
77}
78
79pub fn sign(sk: Fr, message: &[u8]) -> Result<G1Affine> {
80 let q = hash_to_curve(message);
81
82 let sk_int: BigInteger256 = sk.into();
83 let r = q.mul_bigint(sk_int);
84
85 if !r.into_affine().is_on_curve() || !r.into_affine().is_in_correct_subgroup_assuming_on_curve()
86 {
87 return Err(Bn254Error::SignatureNotInSubgroup);
88 }
89
90 Ok(r.into_affine())
91}
92
93pub fn verify(public_key: G2Affine, message: &[u8], signature: G1Affine) -> bool {
94 if !signature.is_in_correct_subgroup_assuming_on_curve() || !signature.is_on_curve() {
95 return false;
96 }
97
98 let q = hash_to_curve(message);
99 let c1 = Bn254::pairing(q, public_key);
100 let c2 = Bn254::pairing(signature, G2Affine::generator());
101 c1 == c2
102}
103
104#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
106pub struct ArkBlsBn254;
107
108macro_rules! impl_ark_serde {
109 ($name:ident, $inner:ty) => {
110 #[derive(Clone, PartialEq, Eq, Debug)]
111 pub struct $name(pub $inner);
112
113 impl PartialOrd for $name {
114 fn partial_cmp(&self, other: &Self) -> Option<blueprint_std::cmp::Ordering> {
115 Some(self.cmp(other))
116 }
117 }
118
119 impl Ord for $name {
120 fn cmp(&self, other: &Self) -> blueprint_std::cmp::Ordering {
121 self.to_bytes().cmp(&other.to_bytes())
122 }
123 }
124
125 impl Hash for $name {
126 fn hash<H: blueprint_std::hash::Hasher>(&self, state: &mut H) {
127 self.to_bytes().hash(state);
128 }
129 }
130
131 impl BytesEncoding for $name {
132 fn to_bytes(&self) -> Vec<u8> {
133 crate::to_bytes(self.0)
134 }
135
136 fn from_bytes(bytes: &[u8]) -> core::result::Result<Self, serde::de::value::Error> {
137 let inner = from_bytes::<$inner>(&bytes);
138 Ok($name(inner))
139 }
140 }
141
142 impl serde::Serialize for $name {
143 fn serialize<S: serde::Serializer>(
144 &self,
145 serializer: S,
146 ) -> core::result::Result<S::Ok, S::Error> {
147 let bytes = self.to_bytes();
148 Vec::serialize(&bytes, serializer)
149 }
150 }
151
152 impl<'de> serde::Deserialize<'de> for $name {
153 fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
154 where
155 D: serde::Deserializer<'de>,
156 {
157 let bytes = <Vec<u8>>::deserialize(deserializer)?;
158 let inner = from_bytes::<$inner>(&bytes);
159 Ok($name(inner))
160 }
161 }
162 };
163}
164
165impl_ark_serde!(ArkBlsBn254Public, G2Affine);
166impl_ark_serde!(ArkBlsBn254Secret, Fr);
167impl_ark_serde!(ArkBlsBn254Signature, G1Affine);
168
169impl zeroize::Zeroize for ArkBlsBn254Secret {
170 fn zeroize(&mut self) {
171 let ptr = (&raw mut self.0).cast::<u8>();
172 let len = core::mem::size_of::<Fr>();
173 unsafe { core::ptr::write_bytes(ptr, 0, len) };
174 core::sync::atomic::compiler_fence(core::sync::atomic::Ordering::SeqCst);
175 }
176}
177
178impl Drop for ArkBlsBn254Secret {
179 fn drop(&mut self) {
180 use zeroize::Zeroize;
181 self.zeroize();
182 }
183}
184
185impl KeyType for ArkBlsBn254 {
186 type Public = ArkBlsBn254Public;
187 type Secret = ArkBlsBn254Secret;
188 type Signature = ArkBlsBn254Signature;
189 type Error = Bn254Error;
190
191 fn key_type_id() -> KeyTypeId {
192 KeyTypeId::Bn254
193 }
194
195 fn generate_with_seed(seed: Option<&[u8]>) -> Result<Self::Secret> {
196 let secret = if let Some(seed) = seed {
197 Fr::from_random_bytes(seed)
198 .ok_or_else(|| Bn254Error::InvalidSeed("None value".to_string()))?
199 } else {
200 #[cfg(feature = "std")]
201 {
202 let mut rng = Self::get_rng();
203 Fr::rand(&mut rng)
204 }
205 #[cfg(not(feature = "std"))]
206 return Err(Bn254Error::InvalidSeed(
207 "Random key generation requires the std feature".into(),
208 ));
209 };
210 Ok(ArkBlsBn254Secret(secret))
211 }
212
213 fn generate_with_string(secret: String) -> Result<Self::Secret> {
214 let secret = Fr::from_str(&secret)
215 .map_err(|()| Bn254Error::InvalidSeed("Invalid secret string".to_string()))?;
216 Ok(ArkBlsBn254Secret(secret))
217 }
218
219 fn public_from_secret(secret: &Self::Secret) -> Self::Public {
220 ArkBlsBn254Public(
221 G2Affine::generator()
222 .mul_bigint(secret.0.into_bigint())
223 .into_affine(),
224 )
225 }
226
227 fn sign_with_secret(secret: &mut Self::Secret, msg: &[u8]) -> Result<Self::Signature> {
228 let signature =
229 sign(secret.0, msg).map_err(|e| Bn254Error::SignatureFailed(e.to_string()))?;
230 Ok(ArkBlsBn254Signature(signature))
231 }
232
233 fn sign_with_secret_pre_hashed(
234 secret: &mut Self::Secret,
235 msg: &[u8; 32],
236 ) -> Result<Self::Signature> {
237 let signature =
238 sign(secret.0, msg).map_err(|e| Bn254Error::SignatureFailed(e.to_string()))?;
239 Ok(ArkBlsBn254Signature(signature))
240 }
241
242 fn verify(public: &Self::Public, msg: &[u8], signature: &Self::Signature) -> bool {
243 verify(public.0, msg, signature.0)
244 }
245}