Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tiny-const-generics #255

Merged
merged 3 commits into from
Apr 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ In addition, the [`curves`](https://github.com/arkworks-rs/curves) repository co

## Build guide

The library compiles on the `stable` toolchain of the Rust compiler. To install the latest version of Rust, first install `rustup` by following the instructions [here](https://rustup.rs/), or via your platform's package manager. Once `rustup` is installed, install the Rust toolchain by invoking:
The library compiles on the `stable` toolchain of the Rust compiler (v 1.51+). To install the latest version of Rust, first install `rustup` by following the instructions [here](https://rustup.rs/), or via your platform's package manager. Once `rustup` is installed, install the Rust toolchain by invoking:
```bash
rustup install stable
```
Expand Down
8 changes: 7 additions & 1 deletion ff/build.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
extern crate rustc_version;
use rustc_version::{version_meta, Channel};
use rustc_version::{version, version_meta, Channel, Version};

fn main() {
println!("cargo:rerun-if-changed=build.rs");
Expand All @@ -15,4 +15,10 @@ fn main() {
if should_use_asm {
println!("cargo:rustc-cfg=use_asm");
}

// TODO: remove this once RFC 2495 ships
if version().expect("Installed rustc version unparseable!") < Version::parse("1.51.0").unwrap()
{
panic!("This code base uses const generics and requires a Rust compiler version greater or equal to 1.51.0");
}
}
218 changes: 90 additions & 128 deletions ff/src/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,151 +14,113 @@ pub trait FromBytes: Sized {
fn read<R: Read>(reader: R) -> IoResult<Self>;
}

macro_rules! array_bytes {
($N:expr) => {
impl ToBytes for [u8; $N] {
#[inline]
fn write<W: Write>(&self, mut writer: W) -> IoResult<()> {
writer.write_all(self)
}
}
impl<const N: usize> ToBytes for [u8; N] {
#[inline]
fn write<W: Write>(&self, mut writer: W) -> IoResult<()> {
writer.write_all(self)
}
}

impl FromBytes for [u8; $N] {
#[inline]
fn read<R: Read>(mut reader: R) -> IoResult<Self> {
let mut arr = [0u8; $N];
reader.read_exact(&mut arr)?;
Ok(arr)
}
}
impl<const N: usize> FromBytes for [u8; N] {
#[inline]
fn read<R: Read>(mut reader: R) -> IoResult<Self> {
let mut arr = [0u8; N];
reader.read_exact(&mut arr)?;
Ok(arr)
}
}

impl ToBytes for [u16; $N] {
#[inline]
fn write<W: Write>(&self, mut writer: W) -> IoResult<()> {
for num in self {
writer.write_all(&num.to_le_bytes())?;
}
Ok(())
}
impl<const N: usize> ToBytes for [u16; N] {
#[inline]
fn write<W: Write>(&self, mut writer: W) -> IoResult<()> {
for num in self {
writer.write_all(&num.to_le_bytes())?;
}
Ok(())
}
}

impl FromBytes for [u16; $N] {
#[inline]
fn read<R: Read>(mut reader: R) -> IoResult<Self> {
let mut res = [0u16; $N];
for num in res.iter_mut() {
let mut bytes = [0u8; 2];
reader.read_exact(&mut bytes)?;
*num = u16::from_le_bytes(bytes);
}
Ok(res)
}
impl<const N: usize> FromBytes for [u16; N] {
#[inline]
fn read<R: Read>(mut reader: R) -> IoResult<Self> {
let mut res = [0u16; N];
for num in res.iter_mut() {
let mut bytes = [0u8; 2];
reader.read_exact(&mut bytes)?;
*num = u16::from_le_bytes(bytes);
}
Ok(res)
}
}

impl ToBytes for [u32; $N] {
#[inline]
fn write<W: Write>(&self, mut writer: W) -> IoResult<()> {
for num in self {
writer.write_all(&num.to_le_bytes())?;
}
Ok(())
}
impl<const N: usize> ToBytes for [u32; N] {
#[inline]
fn write<W: Write>(&self, mut writer: W) -> IoResult<()> {
for num in self {
writer.write_all(&num.to_le_bytes())?;
}
Ok(())
}
}

impl FromBytes for [u32; $N] {
#[inline]
fn read<R: Read>(mut reader: R) -> IoResult<Self> {
let mut res = [0u32; $N];
for num in res.iter_mut() {
let mut bytes = [0u8; 4];
reader.read_exact(&mut bytes)?;
*num = u32::from_le_bytes(bytes);
}
Ok(res)
}
impl<const N: usize> FromBytes for [u32; N] {
#[inline]
fn read<R: Read>(mut reader: R) -> IoResult<Self> {
let mut res = [0u32; N];
for num in res.iter_mut() {
let mut bytes = [0u8; 4];
reader.read_exact(&mut bytes)?;
*num = u32::from_le_bytes(bytes);
}
Ok(res)
}
}

impl ToBytes for [u64; $N] {
#[inline]
fn write<W: Write>(&self, mut writer: W) -> IoResult<()> {
for num in self {
writer.write_all(&num.to_le_bytes())?;
}
Ok(())
}
impl<const N: usize> ToBytes for [u64; N] {
#[inline]
fn write<W: Write>(&self, mut writer: W) -> IoResult<()> {
for num in self {
writer.write_all(&num.to_le_bytes())?;
}
Ok(())
}
}

impl FromBytes for [u64; $N] {
#[inline]
fn read<R: Read>(mut reader: R) -> IoResult<Self> {
let mut res = [0u64; $N];
for num in res.iter_mut() {
let mut bytes = [0u8; 8];
reader.read_exact(&mut bytes)?;
*num = u64::from_le_bytes(bytes);
}
Ok(res)
}
impl<const N: usize> FromBytes for [u64; N] {
#[inline]
fn read<R: Read>(mut reader: R) -> IoResult<Self> {
let mut res = [0u64; N];
for num in res.iter_mut() {
let mut bytes = [0u8; 8];
reader.read_exact(&mut bytes)?;
*num = u64::from_le_bytes(bytes);
}
Ok(res)
}
}

impl ToBytes for [u128; $N] {
#[inline]
fn write<W: Write>(&self, mut writer: W) -> IoResult<()> {
for num in self {
writer.write_all(&num.to_le_bytes())?;
}
Ok(())
}
impl<const N: usize> ToBytes for [u128; N] {
#[inline]
fn write<W: Write>(&self, mut writer: W) -> IoResult<()> {
for num in self {
writer.write_all(&num.to_le_bytes())?;
}
Ok(())
}
}

impl FromBytes for [u128; $N] {
#[inline]
fn read<R: Read>(mut reader: R) -> IoResult<Self> {
let mut res = [0u128; $N];
for num in res.iter_mut() {
let mut bytes = [0u8; 16];
reader.read_exact(&mut bytes)?;
*num = u128::from_le_bytes(bytes);
}
Ok(res)
}
impl<const N: usize> FromBytes for [u128; N] {
#[inline]
fn read<R: Read>(mut reader: R) -> IoResult<Self> {
let mut res = [0u128; N];
for num in res.iter_mut() {
let mut bytes = [0u8; 16];
reader.read_exact(&mut bytes)?;
*num = u128::from_le_bytes(bytes);
}
};
}

array_bytes!(0);
array_bytes!(1);
array_bytes!(2);
array_bytes!(3);
array_bytes!(4);
array_bytes!(5);
array_bytes!(6);
array_bytes!(7);
array_bytes!(8);
array_bytes!(9);
array_bytes!(10);
array_bytes!(11);
array_bytes!(12);
array_bytes!(13);
array_bytes!(14);
array_bytes!(15);
array_bytes!(16);
array_bytes!(17);
array_bytes!(18);
array_bytes!(19);
array_bytes!(20);
array_bytes!(21);
array_bytes!(22);
array_bytes!(23);
array_bytes!(24);
array_bytes!(25);
array_bytes!(26);
array_bytes!(27);
array_bytes!(28);
array_bytes!(29);
array_bytes!(30);
array_bytes!(31);
array_bytes!(32);
Ok(res)
}
}

/// Takes as input a sequence of structs, and converts them to a series of
/// bytes. All traits that implement `Bytes` can be automatically converted to
Expand Down