airbender_crypto/bls12_381/
eip2537.rs1use super::{Fq, Fq2, G1Affine, G2Affine};
7use crate::ark_ec::AffineRepr;
8use crate::ark_ff::PrimeField;
9
10const FIELD_ELEMENT_LEN: usize = 64;
11const G1_LEN: usize = 128;
12const G2_LEN: usize = 256;
13
14#[inline(never)]
15pub fn parse_fq_bytes(input: &[u8; FIELD_ELEMENT_LEN]) -> Option<Fq> {
16 if input[..16].iter().all(|el| *el == 0) == false {
17 return None;
18 }
19 let mut repr = <Fq as PrimeField>::BigInt::zero();
20 let repr_slice = repr.as_mut();
21 for (dst, src) in repr_slice.iter_mut().zip(input[16..].chunks_exact(8).rev()) {
22 *dst = u64::from_be_bytes(src.try_into().unwrap());
23 }
24 Fq::from_bigint(repr)
25}
26
27#[inline(never)]
28pub fn parse_fq2_bytes(input: &[u8; FIELD_ELEMENT_LEN * 2]) -> Option<Fq2> {
29 let c0 = parse_fq_bytes(input[0..64].try_into().ok()?)?;
30 let c1 = parse_fq_bytes(input[64..128].try_into().ok()?)?;
31 Some(Fq2 { c0, c1 })
32}
33
34#[inline(never)]
35pub fn parse_g1_bytes(input: &[u8; G1_LEN]) -> Option<(G1Affine, bool)> {
36 if input.iter().all(|el| *el == 0) {
37 return Some((G1Affine::identity(), false));
38 }
39 let x = parse_fq_bytes(input[0..64].try_into().ok()?)?;
40 let y = parse_fq_bytes(input[64..128].try_into().ok()?)?;
41 let point = G1Affine::new_unchecked(x, y);
42
43 if !point.is_on_curve() {
44 return None;
45 }
46
47 Some((point, true))
48}
49
50#[inline(never)]
51pub fn parse_g2_bytes(input: &[u8; G2_LEN]) -> Option<(G2Affine, bool)> {
52 if input.iter().all(|el| *el == 0) {
53 return Some((G2Affine::identity(), false));
54 }
55 let x = parse_fq2_bytes(input[0..128].try_into().ok()?)?;
56 let y = parse_fq2_bytes(input[128..256].try_into().ok()?)?;
57 let point = G2Affine::new_unchecked(x, y);
58
59 if !point.is_on_curve() {
60 return None;
61 }
62
63 Some((point, true))
64}
65
66#[inline(never)]
67pub fn serialize_fq_bytes(el: Fq, output: &mut [u8; FIELD_ELEMENT_LEN]) {
68 output[..16].fill(0);
69 let bigint = el.into_bigint();
70 let words = bigint.as_ref();
71 for (i, word) in words.iter().take(6).enumerate() {
72 let bytes = word.to_be_bytes();
73 let start = 16 + (5 - i) * 8;
74 output[start..start + 8].copy_from_slice(&bytes);
75 }
76}
77
78#[inline(never)]
79pub fn serialize_fq2_bytes(el: Fq2, output: &mut [u8; FIELD_ELEMENT_LEN * 2]) {
80 let (left, right) = output.split_at_mut(64);
81 serialize_fq_bytes(el.c0, left.try_into().unwrap());
82 serialize_fq_bytes(el.c1, right.try_into().unwrap());
83}
84
85#[inline(never)]
86pub fn serialize_g1_bytes(el: G1Affine, output: &mut [u8; G1_LEN]) {
87 if let Some((x, y)) = el.xy() {
88 let (left, right) = output.split_at_mut(64);
89 serialize_fq_bytes(x, left.try_into().unwrap());
90 serialize_fq_bytes(y, right.try_into().unwrap());
91 } else {
92 output.fill(0);
93 }
94}
95
96#[inline(never)]
97pub fn serialize_g2_bytes(el: G2Affine, output: &mut [u8; G2_LEN]) {
98 if let Some((x, y)) = el.xy() {
99 let (left, right) = output.split_at_mut(128);
100 serialize_fq2_bytes(x, left.try_into().unwrap());
101 serialize_fq2_bytes(y, right.try_into().unwrap());
102 } else {
103 output.fill(0);
104 }
105}