Skip to content

Commit

Permalink
Merge pull request ProvableHQ#1994 from AleoHQ/feat/cast.lossy
Browse files Browse the repository at this point in the history
Adds support for `cast.lossy` opcode
  • Loading branch information
howardwu authored Sep 27, 2023
2 parents 1794128 + f7a483d commit e25ba25
Show file tree
Hide file tree
Showing 71 changed files with 7,344 additions and 4,829 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/benchmarks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ jobs:
- name: Benchmark console/algorithms
run: |
cd console/algorithms
cargo bench --bench poseidon_sponge -- --output-format bencher | tee -a ../../output.txt
cargo bench --bench poseidon -- --output-format bencher | tee -a ../../output.txt
cargo bench --bench elligator2 -- --output-format bencher | tee -a ../../output.txt
cd ../..
- name: Benchmark console/collections
Expand Down
5 changes: 5 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion circuit/algorithms/src/poseidon/hash_to_scalar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl<E: Environment, const RATE: usize> HashToScalar for Poseidon<E, RATE> {
let output = self.hash(input);
// Convert the output to the scalar field,
// truncating to the size in data bits (1 bit less than the MODULUS) of the scalar.
Scalar::from_field_lossy(output)
Scalar::from_field_lossy(&output)
}
}

Expand Down
8 changes: 8 additions & 0 deletions circuit/program/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ optional = true
path = "../account"
version = "=0.14.6"

[dependencies.snarkvm-circuit-algorithms]
path = "../algorithms"
version = "=0.14.6"

[dependencies.snarkvm-circuit-collections]
path = "../collections"
version = "=0.14.6"
Expand All @@ -35,6 +39,10 @@ version = "=0.14.6"
[dependencies.paste]
version = "1.0"

[dev-dependencies.console_root]
package = "snarkvm-console"
path = "../../console"

[dev-dependencies.console]
package = "snarkvm-console-program"
path = "../../console/program"
Expand Down
190 changes: 190 additions & 0 deletions circuit/program/src/data/literal/cast/boolean.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
// Copyright (C) 2019-2023 Aleo Systems Inc.
// This file is part of the snarkVM library.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use super::*;

impl<E: Environment> Cast<Address<E>> for Boolean<E> {
/// Casts a `Boolean` to an `Address`.
#[inline]
fn cast(&self) -> Address<E> {
self.cast_lossy()
}
}

impl<E: Environment> Cast<Boolean<E>> for Boolean<E> {
/// Casts a `Boolean` to a `Boolean`.
#[inline]
fn cast(&self) -> Boolean<E> {
self.cast_lossy()
}
}

impl<E: Environment> Cast<Field<E>> for Boolean<E> {
/// Casts a `Boolean` to a `Field`.
#[inline]
fn cast(&self) -> Field<E> {
self.cast_lossy()
}
}

impl<E: Environment> Cast<Group<E>> for Boolean<E> {
/// Casts a `Boolean` to a `Group`.
#[inline]
fn cast(&self) -> Group<E> {
self.cast_lossy()
}
}

impl<E: Environment, I: IntegerType> Cast<Integer<E, I>> for Boolean<E> {
/// Casts a `Boolean` to an `Integer`.
#[inline]
fn cast(&self) -> Integer<E, I> {
self.cast_lossy()
}
}

impl<E: Environment> Cast<Scalar<E>> for Boolean<E> {
/// Casts a `Boolean` to a `Scalar`.
#[inline]
fn cast(&self) -> Scalar<E> {
self.cast_lossy()
}
}

#[cfg(test)]
mod tests {
use super::*;
use console::Cast as _;
use console_root::{network::Testnet3, prelude::TestRng};
use snarkvm_circuit_types::environment::{count_is, Circuit, Eject, Inject, Mode, UpdatableCount};

use std::fmt::Debug;

const ITERATIONS: usize = 2;

fn sample_values(
i: usize,
mode: Mode,
_: &mut TestRng,
) -> (console_root::types::Boolean<Testnet3>, Boolean<Circuit>) {
(console_root::types::Boolean::new(i % 2 == 0), Boolean::new(mode, i % 2 == 0))
}

impl_check_cast!(cast, Boolean<Circuit>, console_root::types::Boolean::<Testnet3>);

#[test]
fn test_boolean_to_address() {
check_cast::<Address<Circuit>, console_root::types::Address<Testnet3>>(Mode::Constant, count_is!(10, 0, 0, 0));
check_cast::<Address<Circuit>, console_root::types::Address<Testnet3>>(Mode::Public, count_is!(10, 0, 0, 0));
check_cast::<Address<Circuit>, console_root::types::Address<Testnet3>>(Mode::Private, count_is!(10, 0, 0, 0));
}

#[test]
fn test_boolean_to_boolean() {
check_cast::<Boolean<Circuit>, console_root::types::Boolean<Testnet3>>(Mode::Constant, count_is!(0, 0, 0, 0));
check_cast::<Boolean<Circuit>, console_root::types::Boolean<Testnet3>>(Mode::Public, count_is!(0, 0, 0, 0));
check_cast::<Boolean<Circuit>, console_root::types::Boolean<Testnet3>>(Mode::Private, count_is!(0, 0, 0, 0));
}

#[test]
fn test_boolean_to_field() {
check_cast::<Field<Circuit>, console_root::types::Field<Testnet3>>(Mode::Constant, count_is!(0, 0, 0, 0));
check_cast::<Field<Circuit>, console_root::types::Field<Testnet3>>(Mode::Public, count_is!(0, 0, 0, 0));
check_cast::<Field<Circuit>, console_root::types::Field<Testnet3>>(Mode::Private, count_is!(0, 0, 0, 0));
}

#[test]
fn test_boolean_to_group() {
check_cast::<Group<Circuit>, console_root::types::Group<Testnet3>>(Mode::Constant, count_is!(10, 0, 0, 0));
check_cast::<Group<Circuit>, console_root::types::Group<Testnet3>>(Mode::Public, count_is!(10, 0, 0, 0));
check_cast::<Group<Circuit>, console_root::types::Group<Testnet3>>(Mode::Private, count_is!(10, 0, 0, 0));
}

#[test]
fn test_boolean_to_i8() {
check_cast::<I8<Circuit>, console_root::types::I8<Testnet3>>(Mode::Constant, count_is!(16, 0, 0, 0));
check_cast::<I8<Circuit>, console_root::types::I8<Testnet3>>(Mode::Public, count_is!(16, 0, 0, 0));
check_cast::<I8<Circuit>, console_root::types::I8<Testnet3>>(Mode::Private, count_is!(16, 0, 0, 0));
}

#[test]
fn test_boolean_to_i16() {
check_cast::<I16<Circuit>, console_root::types::I16<Testnet3>>(Mode::Constant, count_is!(32, 0, 0, 0));
check_cast::<I16<Circuit>, console_root::types::I16<Testnet3>>(Mode::Public, count_is!(32, 0, 0, 0));
check_cast::<I16<Circuit>, console_root::types::I16<Testnet3>>(Mode::Private, count_is!(32, 0, 0, 0));
}

#[test]
fn test_boolean_to_i32() {
check_cast::<I32<Circuit>, console_root::types::I32<Testnet3>>(Mode::Constant, count_is!(64, 0, 0, 0));
check_cast::<I32<Circuit>, console_root::types::I32<Testnet3>>(Mode::Public, count_is!(64, 0, 0, 0));
check_cast::<I32<Circuit>, console_root::types::I32<Testnet3>>(Mode::Private, count_is!(64, 0, 0, 0));
}

#[test]
fn test_boolean_to_i64() {
check_cast::<I64<Circuit>, console_root::types::I64<Testnet3>>(Mode::Constant, count_is!(128, 0, 0, 0));
check_cast::<I64<Circuit>, console_root::types::I64<Testnet3>>(Mode::Public, count_is!(128, 0, 0, 0));
check_cast::<I64<Circuit>, console_root::types::I64<Testnet3>>(Mode::Private, count_is!(128, 0, 0, 0));
}

#[test]
fn test_boolean_to_i128() {
check_cast::<I128<Circuit>, console_root::types::I128<Testnet3>>(Mode::Constant, count_is!(256, 0, 0, 0));
check_cast::<I128<Circuit>, console_root::types::I128<Testnet3>>(Mode::Public, count_is!(256, 0, 0, 0));
check_cast::<I128<Circuit>, console_root::types::I128<Testnet3>>(Mode::Private, count_is!(256, 0, 0, 0));
}

#[test]
fn test_boolean_to_scalar() {
check_cast::<Scalar<Circuit>, console_root::types::Scalar<Testnet3>>(Mode::Constant, count_is!(2, 0, 0, 0));
check_cast::<Scalar<Circuit>, console_root::types::Scalar<Testnet3>>(Mode::Public, count_is!(2, 0, 0, 0));
check_cast::<Scalar<Circuit>, console_root::types::Scalar<Testnet3>>(Mode::Private, count_is!(2, 0, 0, 0));
}

#[test]
fn test_boolean_to_u8() {
check_cast::<U8<Circuit>, console_root::types::U8<Testnet3>>(Mode::Constant, count_is!(16, 0, 0, 0));
check_cast::<U8<Circuit>, console_root::types::U8<Testnet3>>(Mode::Public, count_is!(16, 0, 0, 0));
check_cast::<U8<Circuit>, console_root::types::U8<Testnet3>>(Mode::Private, count_is!(16, 0, 0, 0));
}

#[test]
fn test_boolean_to_u16() {
check_cast::<U16<Circuit>, console_root::types::U16<Testnet3>>(Mode::Constant, count_is!(32, 0, 0, 0));
check_cast::<U16<Circuit>, console_root::types::U16<Testnet3>>(Mode::Public, count_is!(32, 0, 0, 0));
check_cast::<U16<Circuit>, console_root::types::U16<Testnet3>>(Mode::Private, count_is!(32, 0, 0, 0));
}

#[test]
fn test_boolean_to_u32() {
check_cast::<U32<Circuit>, console_root::types::U32<Testnet3>>(Mode::Constant, count_is!(64, 0, 0, 0));
check_cast::<U32<Circuit>, console_root::types::U32<Testnet3>>(Mode::Public, count_is!(64, 0, 0, 0));
check_cast::<U32<Circuit>, console_root::types::U32<Testnet3>>(Mode::Private, count_is!(64, 0, 0, 0));
}

#[test]
fn test_boolean_to_u64() {
check_cast::<U64<Circuit>, console_root::types::U64<Testnet3>>(Mode::Constant, count_is!(128, 0, 0, 0));
check_cast::<U64<Circuit>, console_root::types::U64<Testnet3>>(Mode::Public, count_is!(128, 0, 0, 0));
check_cast::<U64<Circuit>, console_root::types::U64<Testnet3>>(Mode::Private, count_is!(128, 0, 0, 0));
}

#[test]
fn test_boolean_to_u128() {
check_cast::<U128<Circuit>, console_root::types::U128<Testnet3>>(Mode::Constant, count_is!(256, 0, 0, 0));
check_cast::<U128<Circuit>, console_root::types::U128<Testnet3>>(Mode::Public, count_is!(256, 0, 0, 0));
check_cast::<U128<Circuit>, console_root::types::U128<Testnet3>>(Mode::Private, count_is!(256, 0, 0, 0));
}
}
Loading

0 comments on commit e25ba25

Please sign in to comment.