arnaucube
arnaucube/ark-curves-cherry-pickedPublic Self-hosted repository
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}