arkworks_native_gadgets/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2
3use ark_ff::{BigInteger, PrimeField};
4use ark_std::{boxed::Box, vec::Vec};
5
6#[macro_use]
7pub extern crate ark_std;
8
9pub mod merkle_tree;
10pub mod mimc;
11pub mod poseidon;
12
13pub type Error = Box<dyn ark_std::error::Error>;
14
15pub mod prelude {
16	pub use ark_crypto_primitives;
17	pub use ark_ff;
18	pub use ark_std;
19}
20
21// bytes field is assumed to contain concatenated, Big-endian encoded chunks.
22pub fn to_field_elements<F: PrimeField>(bytes: &[u8]) -> Result<Vec<F>, Error> {
23	let max_size_bytes = F::BigInt::NUM_LIMBS * 8;
24
25	// Pad the input with zeros to prevent crashes in arkworks
26	let padding_len = (max_size_bytes - (bytes.len() % max_size_bytes)) % max_size_bytes;
27	let padded_input: Vec<u8> = bytes
28		.iter()
29		.cloned()
30		.chain(core::iter::repeat(0u8).take(padding_len))
31		.collect();
32
33	// Reverse all chunks so the values are formatted in little-endian.
34	// This is necessary because arkworks assumes little-endian.
35	let mut reversed_chunks: Vec<u8> = Vec::with_capacity(bytes.len() + padding_len);
36
37	for chunk in padded_input.chunks(max_size_bytes) {
38		reversed_chunks.extend(chunk.iter().rev());
39	}
40
41	// Read the chunks into arkworks to convert into field elements.
42	let res = reversed_chunks
43		.chunks(max_size_bytes)
44		.map(F::read)
45		.collect::<Result<Vec<_>, _>>()?;
46	Ok(res)
47}
48
49pub fn from_field_elements<F: PrimeField>(elts: &[F]) -> Result<Vec<u8>, Error> {
50	let res = elts.iter().fold(vec![], |mut acc, prev| {
51		acc.extend_from_slice(&prev.into_repr().to_bytes_be());
52		acc
53	});
54
55	Ok(res)
56}