|
1 | 1 | use std::{cmp::Ordering, fmt}; |
2 | 2 |
|
3 | 3 | use bn::{AffineG2, Fq, Fq2, Group, G2}; |
| 4 | +use borsh::{BorshDeserialize, BorshSerialize}; |
4 | 5 | use serde::{Deserialize, Serialize, Serializer}; |
5 | 6 |
|
6 | 7 | use crate::{ |
@@ -218,3 +219,107 @@ fn get_ys_from_x_g2(x: Fq2) -> Result<(Fq2, Fq2), Error> { |
218 | 219 | Ok((neg_y, y)) |
219 | 220 | } |
220 | 221 | } |
| 222 | + |
| 223 | +impl BorshSerialize for SAffineG2 { |
| 224 | + fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> { |
| 225 | + let mut projective: G2 = (self.0).into(); |
| 226 | + projective.normalize(); |
| 227 | + let (x, y) = (projective.x(), projective.y()); |
| 228 | + |
| 229 | + // Serialize x coordinate (Fq2: real + imaginary) |
| 230 | + let mut x_real_bytes = [0u8; 32]; |
| 231 | + x.real().to_big_endian(&mut x_real_bytes).map_err(|_| { |
| 232 | + std::io::Error::new( |
| 233 | + std::io::ErrorKind::InvalidData, |
| 234 | + "Failed to serialize x real part", |
| 235 | + ) |
| 236 | + })?; |
| 237 | + writer.write_all(&x_real_bytes)?; |
| 238 | + |
| 239 | + let mut x_imag_bytes = [0u8; 32]; |
| 240 | + x.imaginary() |
| 241 | + .to_big_endian(&mut x_imag_bytes) |
| 242 | + .map_err(|_| { |
| 243 | + std::io::Error::new( |
| 244 | + std::io::ErrorKind::InvalidData, |
| 245 | + "Failed to serialize x imaginary part", |
| 246 | + ) |
| 247 | + })?; |
| 248 | + writer.write_all(&x_imag_bytes)?; |
| 249 | + |
| 250 | + // Serialize y coordinate (Fq2: real + imaginary) |
| 251 | + let mut y_real_bytes = [0u8; 32]; |
| 252 | + y.real().to_big_endian(&mut y_real_bytes).map_err(|_| { |
| 253 | + std::io::Error::new( |
| 254 | + std::io::ErrorKind::InvalidData, |
| 255 | + "Failed to serialize y real part", |
| 256 | + ) |
| 257 | + })?; |
| 258 | + writer.write_all(&y_real_bytes)?; |
| 259 | + |
| 260 | + let mut y_imag_bytes = [0u8; 32]; |
| 261 | + y.imaginary() |
| 262 | + .to_big_endian(&mut y_imag_bytes) |
| 263 | + .map_err(|_| { |
| 264 | + std::io::Error::new( |
| 265 | + std::io::ErrorKind::InvalidData, |
| 266 | + "Failed to serialize y imaginary part", |
| 267 | + ) |
| 268 | + })?; |
| 269 | + writer.write_all(&y_imag_bytes)?; |
| 270 | + |
| 271 | + Ok(()) |
| 272 | + } |
| 273 | +} |
| 274 | + |
| 275 | +impl BorshDeserialize for SAffineG2 { |
| 276 | + fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> { |
| 277 | + // Read x coordinate components |
| 278 | + let mut x_real_bytes = [0u8; 32]; |
| 279 | + reader.read_exact(&mut x_real_bytes)?; |
| 280 | + let x_real = Fq::from_slice(&x_real_bytes).map_err(|_| { |
| 281 | + std::io::Error::new( |
| 282 | + std::io::ErrorKind::InvalidData, |
| 283 | + "Failed to deserialize x real part", |
| 284 | + ) |
| 285 | + })?; |
| 286 | + |
| 287 | + let mut x_imag_bytes = [0u8; 32]; |
| 288 | + reader.read_exact(&mut x_imag_bytes)?; |
| 289 | + let x_imag = Fq::from_slice(&x_imag_bytes).map_err(|_| { |
| 290 | + std::io::Error::new( |
| 291 | + std::io::ErrorKind::InvalidData, |
| 292 | + "Failed to deserialize x imaginary part", |
| 293 | + ) |
| 294 | + })?; |
| 295 | + |
| 296 | + // Read y coordinate components |
| 297 | + let mut y_real_bytes = [0u8; 32]; |
| 298 | + reader.read_exact(&mut y_real_bytes)?; |
| 299 | + let y_real = Fq::from_slice(&y_real_bytes).map_err(|_| { |
| 300 | + std::io::Error::new( |
| 301 | + std::io::ErrorKind::InvalidData, |
| 302 | + "Failed to deserialize y real part", |
| 303 | + ) |
| 304 | + })?; |
| 305 | + |
| 306 | + let mut y_imag_bytes = [0u8; 32]; |
| 307 | + reader.read_exact(&mut y_imag_bytes)?; |
| 308 | + let y_imag = Fq::from_slice(&y_imag_bytes).map_err(|_| { |
| 309 | + std::io::Error::new( |
| 310 | + std::io::ErrorKind::InvalidData, |
| 311 | + "Failed to deserialize y imaginary part", |
| 312 | + ) |
| 313 | + })?; |
| 314 | + |
| 315 | + let x = Fq2::new(x_real, x_imag); |
| 316 | + let y = Fq2::new(y_real, y_imag); |
| 317 | + let z = Fq2::one(); |
| 318 | + |
| 319 | + let projective = G2::new(x, y, z); |
| 320 | + let g2 = AffineG2::from_jacobian(projective) |
| 321 | + .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::InvalidData, "Invalid point"))?; |
| 322 | + |
| 323 | + Ok(SAffineG2(g2)) |
| 324 | + } |
| 325 | +} |
0 commit comments