Given an element `F`, break it into chunks where each chunk is of `chunk_bit_size` bits. This is essentially an n-ary representation where n is `chunk_bit_size`. Returns big-endian representation.
(message: &F, chunk_bit_size: u8)
| 15 | /// Given an element `F`, break it into chunks where each chunk is of `chunk_bit_size` bits. This is |
| 16 | /// essentially an n-ary representation where n is `chunk_bit_size`. Returns big-endian representation. |
| 17 | pub fn decompose<F: PrimeField>(message: &F, chunk_bit_size: u8) -> crate::Result<Vec<CHUNK_TYPE>> { |
| 18 | let bytes = message.into_bigint().to_bytes_be(); |
| 19 | let mut decomposition = Vec::<CHUNK_TYPE>::new(); |
| 20 | match chunk_bit_size { |
| 21 | 4 => { |
| 22 | for b in bytes { |
| 23 | decomposition.push((b >> 4) as CHUNK_TYPE); |
| 24 | decomposition.push((b & 15) as CHUNK_TYPE); |
| 25 | } |
| 26 | } |
| 27 | 8 => { |
| 28 | for b in bytes { |
| 29 | decomposition.push(b as CHUNK_TYPE); |
| 30 | } |
| 31 | } |
| 32 | 16 => { |
| 33 | // Process 2 bytes at a time |
| 34 | for bytes_2 in bytes.chunks(2) { |
| 35 | let mut b = (bytes_2[0] as CHUNK_TYPE) << (8 as CHUNK_TYPE); |
| 36 | if bytes_2.len() > 1 { |
| 37 | b += bytes_2[1] as CHUNK_TYPE; |
| 38 | } |
| 39 | decomposition.push(b); |
| 40 | } |
| 41 | } |
| 42 | b => return Err(SaverError::UnexpectedBase(b)), |
| 43 | } |
| 44 | Ok(decomposition) |
| 45 | } |
| 46 | |
| 47 | /// Recreate a field element back from output of `decompose`. Assumes big-endian representation in `decomposed` |
| 48 | pub fn compose<F: PrimeField>(decomposed: &[CHUNK_TYPE], chunk_bit_size: u8) -> crate::Result<F> { |