ark-curves-cherry-picked/bls12_381/src/curves/util.rs
bls12_381/src/curves/util.rsRaw
1use ark_ec::{short_weierstrass::Affine, AffineRepr};
2use ark_ff::{BigInteger384, PrimeField};
3use ark_serialize::SerializationError;
4
5use crate::{g1::Config as G1Config, g2::Config as G2Config, Fq, Fq2, G1Affine, G2Affine};
6
7pub const G1_SERIALIZED_SIZE: usize = 48;
8pub const G2_SERIALIZED_SIZE: usize = 96;
9
10pub struct EncodingFlags {
11 pub is_compressed: bool,
12 pub is_infinity: bool,
13 pub is_lexographically_largest: bool,
14}
15
16impl EncodingFlags {
17 pub fn get_flags(bytes: &[u8]) -> Self {
18 let compression_flag_set = (bytes[0] >> 7) & 1;
19 let infinity_flag_set = (bytes[0] >> 6) & 1;
20 let sort_flag_set = (bytes[0] >> 5) & 1;
21
22 Self {
23 is_compressed: compression_flag_set == 1,
24 is_infinity: infinity_flag_set == 1,
25 is_lexographically_largest: sort_flag_set == 1,
26 }
27 }
28 pub fn encode_flags(&self, bytes: &mut [u8]) {
29 if self.is_compressed {
30 bytes[0] |= 1 << 7;
31 }
32
33 if self.is_infinity {
34 bytes[0] |= 1 << 6;
35 }
36
37 if self.is_compressed && !self.is_infinity && self.is_lexographically_largest {
38 bytes[0] |= 1 << 5;
39 }
40 }
41}
42
43pub(crate) fn deserialize_fq(bytes: [u8; 48]) -> Option<Fq> {
44 let mut tmp = BigInteger384::new([0, 0, 0, 0, 0, 0]);
45
46 // Note: The following unwraps are if the compiler cannot convert
47 // the byte slice into [u8;8], we know this is infallible since we
48 // are providing the indices at compile time and bytes has a fixed size
49 tmp.0[5] = u64::from_be_bytes(<[u8; 8]>::try_from(&bytes[0..8]).unwrap());
50 tmp.0[4] = u64::from_be_bytes(<[u8; 8]>::try_from(&bytes[8..16]).unwrap());
51 tmp.0[3] = u64::from_be_bytes(<[u8; 8]>::try_from(&bytes[16..24]).unwrap());
52 tmp.0[2] = u64::from_be_bytes(<[u8; 8]>::try_from(&bytes[24..32]).unwrap());
53 tmp.0[1] = u64::from_be_bytes(<[u8; 8]>::try_from(&bytes[32..40]).unwrap());
54 tmp.0[0] = u64::from_be_bytes(<[u8; 8]>::try_from(&bytes[40..48]).unwrap());
55
56 Fq::from_bigint(tmp)
57}
58
59pub(crate) fn serialize_fq(field: Fq) -> [u8; 48] {
60 let mut result = [0u8; 48];
61
62 let rep = field.into_bigint();
63
64 result[0..8].copy_from_slice(&rep.0[5].to_be_bytes());
65 result[8..16].copy_from_slice(&rep.0[4].to_be_bytes());
66 result[16..24].copy_from_slice(&rep.0[3].to_be_bytes());
67 result[24..32].copy_from_slice(&rep.0[2].to_be_bytes());
68 result[32..40].copy_from_slice(&rep.0[1].to_be_bytes());
69 result[40..48].copy_from_slice(&rep.0[0].to_be_bytes());
70
71 result
72}
73
74pub(crate) fn read_fq_with_offset(
75 bytes: &[u8],
76 offset: usize,
77 mask: bool,
78) -> Result<Fq, ark_serialize::SerializationError> {
79 let mut tmp = [0; G1_SERIALIZED_SIZE];
80 // read `G1_SERIALIZED_SIZE` bytes
81 tmp.copy_from_slice(&bytes[offset * G1_SERIALIZED_SIZE..G1_SERIALIZED_SIZE * (offset + 1)]);
82
83 if mask {
84 // Mask away the flag bits
85 tmp[0] &= 0b0001_1111;
86 }
87 deserialize_fq(tmp).ok_or(SerializationError::InvalidData)
88}
89
90pub(crate) fn read_g1_compressed<R: ark_serialize::Read>(
91 mut reader: R,
92) -> Result<Affine<G1Config>, ark_serialize::SerializationError> {
93 let mut bytes = [0u8; G1_SERIALIZED_SIZE];
94 reader
95 .read_exact(&mut bytes)
96 .ok()
97 .ok_or(SerializationError::InvalidData)?;
98
99 // Obtain the three flags from the start of the byte sequence
100 let flags = EncodingFlags::get_flags(&bytes[..]);
101
102 // we expect to be deserializing a compressed point
103 if !flags.is_compressed {
104 return Err(SerializationError::UnexpectedFlags);
105 }
106
107 if flags.is_infinity {
108 return Ok(G1Affine::zero());
109 }
110
111 // Attempt to obtain the x-coordinate
112 let x = read_fq_with_offset(&bytes, 0, true)?;
113
114 let p = G1Affine::get_point_from_x_unchecked(x, flags.is_lexographically_largest)
115 .ok_or(SerializationError::InvalidData)?;
116
117 Ok(p)
118}
119
120pub(crate) fn read_g1_uncompressed<R: ark_serialize::Read>(
121 mut reader: R,
122) -> Result<Affine<G1Config>, ark_serialize::SerializationError> {
123 let mut bytes = [0u8; 2 * G1_SERIALIZED_SIZE];
124 reader
125 .read_exact(&mut bytes)
126 .map_err(|_| SerializationError::InvalidData)?;
127
128 // Obtain the three flags from the start of the byte sequence
129 let flags = EncodingFlags::get_flags(&bytes[..]);
130
131 // we expect to be deserializing an uncompressed point
132 if flags.is_compressed {
133 return Err(SerializationError::UnexpectedFlags);
134 }
135
136 if flags.is_infinity {
137 return Ok(G1Affine::zero());
138 }
139
140 // Attempt to obtain the x-coordinate
141 let x = read_fq_with_offset(&bytes, 0, true)?;
142 // Attempt to obtain the y-coordinate
143 let y = read_fq_with_offset(&bytes, 1, false)?;
144
145 let p = G1Affine::new_unchecked(x, y);
146
147 Ok(p)
148}
149
150pub(crate) fn read_g2_compressed<R: ark_serialize::Read>(
151 mut reader: R,
152) -> Result<Affine<G2Config>, ark_serialize::SerializationError> {
153 let mut bytes = [0u8; G2_SERIALIZED_SIZE];
154 reader
155 .read_exact(&mut bytes)
156 .map_err(|_| SerializationError::InvalidData)?;
157
158 // Obtain the three flags from the start of the byte sequence
159 let flags = EncodingFlags::get_flags(&bytes);
160
161 // we expect to be deserializing a compressed point
162 if !flags.is_compressed {
163 return Err(SerializationError::UnexpectedFlags);
164 }
165
166 if flags.is_infinity {
167 return Ok(G2Affine::zero());
168 }
169
170 // Attempt to obtain the x-coordinate
171 let xc1 = read_fq_with_offset(&bytes, 0, true)?;
172 let xc0 = read_fq_with_offset(&bytes, 1, false)?;
173
174 let x = Fq2::new(xc0, xc1);
175
176 let p = G2Affine::get_point_from_x_unchecked(x, flags.is_lexographically_largest)
177 .ok_or(SerializationError::InvalidData)?;
178
179 Ok(p)
180}
181
182pub(crate) fn read_g2_uncompressed<R: ark_serialize::Read>(
183 mut reader: R,
184) -> Result<Affine<G2Config>, ark_serialize::SerializationError> {
185 let mut bytes = [0u8; 2 * G2_SERIALIZED_SIZE];
186 reader
187 .read_exact(&mut bytes)
188 .map_err(|_| SerializationError::InvalidData)?;
189
190 // Obtain the three flags from the start of the byte sequence
191 let flags = EncodingFlags::get_flags(&bytes);
192
193 // we expect to be deserializing an uncompressed point
194 if flags.is_compressed {
195 return Err(SerializationError::UnexpectedFlags);
196 }
197
198 if flags.is_infinity {
199 return Ok(G2Affine::zero());
200 }
201
202 // Attempt to obtain the x-coordinate
203 let xc1 = read_fq_with_offset(&bytes, 0, true)?;
204 let xc0 = read_fq_with_offset(&bytes, 1, false)?;
205 let x = Fq2::new(xc0, xc1);
206
207 // Attempt to obtain the y-coordinate
208 let yc1 = read_fq_with_offset(&bytes, 2, false)?;
209 let yc0 = read_fq_with_offset(&bytes, 3, false)?;
210 let y = Fq2::new(yc0, yc1);
211
212 let p = G2Affine::new_unchecked(x, y);
213
214 Ok(p)
215}