diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..235989c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,167 @@ +name: CI + +on: + pull_request: + push: + branches: master + +env: + MSRV: 1.51.0 + RUSTFLAGS: "-Dwarnings" + CARGO_INCREMENTAL: 0 + RUST_BACKTRACE: 1 + +jobs: + set-msrv: + runs-on: ubuntu-latest + outputs: + msrv: ${{ steps.msrv.outputs.msrv }} + steps: + - uses: actions/checkout@v2 + - id: msrv + run: echo "::set-output name=msrv::$(echo $MSRV)" + + linux_foreign: + strategy: + matrix: + include: + # 64-bit Linux/arm64 + - target: aarch64-unknown-linux-gnu + rust: nightly + arch: aarch64 + + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - uses: uraimo/run-on-arch-action@v2.1.1 + name: Run commands + id: runcmd + with: + arch: aarch64 + distro: ubuntu18.04 + + # Not required, but speeds up builds by storing container images in + # a GitHub package registry. + githubToken: ${{ github.token }} + + install: | + apt-get update -q -y + apt-get install -q -y ocl-icd-opencl-dev curl build-essential + curl https://sh.rustup.rs -sSf | sh -s -- --profile minimal --default-toolchain ${{ matrix.rust }} -y + source $HOME/.cargo/env + + run: | + $HOME/.cargo/bin/cargo test --release --target ${{ matrix.target }} + $HOME/.cargo/bin/cargo test --release --features portable --target ${{ matrix.target }} + + # Linux tests + linux: + needs: set-msrv + strategy: + matrix: + include: + # 32-bit Linux/x86 + - target: i686-unknown-linux-gnu + rust: ${{needs.set-msrv.outputs.msrv}} + deps: sudo apt update && sudo apt install gcc-multilib + - target: i686-unknown-linux-gnu + rust: stable + deps: sudo apt update && sudo apt install gcc-multilib + + # 64-bit Linux/x86_64 + - target: x86_64-unknown-linux-gnu + rust: ${{needs.set-msrv.outputs.msrv}} + - target: x86_64-unknown-linux-gnu + rust: stable + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + target: ${{ matrix.target }} + override: true + - name: Install opencl + run: sudo apt-get install -y ocl-icd-opencl-dev + - run: ${{ matrix.deps }} + - run: cargo test --target ${{ matrix.target }} + - run: cargo test --target ${{ matrix.target }} --features portable + + # macOS tests + macos: + needs: set-msrv + strategy: + matrix: + toolchain: + - ${{needs.set-msrv.outputs.msrv}} + - stable + + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.toolchain }} + target: x86_64-apple-darwin + override: true + - run: cargo test + - run: cargo test --features portable + + # Windows tests + windows: + needs: set-msrv + strategy: + matrix: + include: + # 64-bit Windows (MSVC) + - target: x86_64-pc-windows-msvc + toolchain: stable + + runs-on: windows-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.toolchain }} + target: ${{ matrix.target }} + override: true + - uses: msys2/setup-msys2@v2 + - run: cargo test --target ${{ matrix.target }} + - run: cargo test --target ${{ matrix.target }} --features portable + + clippy_check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - run: rustup component add clippy + - uses: actions-rs/clippy-check@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + args: --all-features + + check_fmt_and_docs: + name: Checking fmt and docs + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: nightly + override: true + components: rustfmt + + - name: setup + run: | + rustup component add rustfmt + rustc --version + - name: fmt + run: cargo fmt --all -- --check + + - name: Docs + run: cargo doc \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index e6c993a..1c23744 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,8 +8,6 @@ #[cfg(not(target_endian = "little"))] compile_error!("blstrs is only supported on little endian architectures"); -#[cfg(not(target_pointer_width = "64"))] -compile_error!("blstrs is only supported on 64bit architectures"); #[macro_use] mod macros; diff --git a/src/scalar.rs b/src/scalar.rs index b224675..d5c7141 100644 --- a/src/scalar.rs +++ b/src/scalar.rs @@ -41,6 +41,19 @@ const MODULUS: [u64; 4] = [ 0x73ed_a753_299d_7d48, ]; +/// The modulus as u32 limbs. +#[cfg(not(target_pointer_width = "64"))] +const MODULUS_LIMBS_32: [u32; 8] = [ + 0x0000_0001, + 0xffff_ffff, + 0xfffe_5bfe, + 0x53bd_a402, + 0x09a1_d805, + 0x3339_d808, + 0x299d_7d48, + 0x73ed_a753, +]; + // Little-endian non-Montgomery form not reduced mod p. const MODULUS_REPR: [u8; 32] = [ 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x5b, 0xfe, 0xff, 0x02, 0xa4, 0xbd, 0x53, @@ -465,10 +478,17 @@ impl PrimeField for Scalar { } } +#[cfg(not(target_pointer_width = "64"))] +type ReprBits = [u32; 8]; + +#[cfg(target_pointer_width = "64")] +type ReprBits = [u64; 4]; + impl PrimeFieldBits for Scalar { // Representation in non-Montgomery form. - type ReprBits = [u64; 4]; + type ReprBits = ReprBits; + #[cfg(target_pointer_width = "64")] fn to_le_bits(&self) -> FieldBits { let mut limbs = [0u64; 4]; unsafe { blst_uint64_from_fr(limbs.as_mut_ptr(), &self.0) }; @@ -476,7 +496,29 @@ impl PrimeFieldBits for Scalar { FieldBits::new(limbs) } + #[cfg(not(target_pointer_width = "64"))] + fn to_le_bits(&self) -> FieldBits { + let bytes = self.to_bytes_le(); + let limbs = [ + u32::from_le_bytes(bytes[0..4].try_into().unwrap()), + u32::from_le_bytes(bytes[4..8].try_into().unwrap()), + u32::from_le_bytes(bytes[8..12].try_into().unwrap()), + u32::from_le_bytes(bytes[12..16].try_into().unwrap()), + u32::from_le_bytes(bytes[16..20].try_into().unwrap()), + u32::from_le_bytes(bytes[20..24].try_into().unwrap()), + u32::from_le_bytes(bytes[24..28].try_into().unwrap()), + u32::from_le_bytes(bytes[28..32].try_into().unwrap()), + ]; + FieldBits::new(limbs) + } + fn char_le_bits() -> FieldBits { + #[cfg(not(target_pointer_width = "64"))] + { + FieldBits::new(MODULUS_LIMBS_32) + } + + #[cfg(target_pointer_width = "64")] FieldBits::new(MODULUS) } }