Skip to content

Commit

Permalink
Tiny-const-generics (#255)
Browse files Browse the repository at this point in the history
* updates bytes to use const generics

* Add a check for a minimum rustc version in ff

* Specify min version for the compiler in README
  • Loading branch information
huitseeker committed Apr 17, 2021
1 parent 0bd355b commit 8df29c4
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 130 deletions.
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

0 comments on commit 8df29c4

Please sign in to comment.