Skip to content

Commit

Permalink
feat: pasta gpu
Browse files Browse the repository at this point in the history
  • Loading branch information
DrPeterVanNostrand committed Mar 3, 2022
1 parent 9fa4ed0 commit 952341e
Show file tree
Hide file tree
Showing 36 changed files with 671 additions and 696 deletions.
8 changes: 5 additions & 3 deletions filecoin-hashers/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ bellperson = "0.18.0"
blstrs = "0.4.0"
generic-array = "0.14.4"
merkletree = "0.21.0"
ec-gpu = "0.1.0"
ff = "0.11.0"
anyhow = "1.0.34"
serde = "1.0.117"
rand = "0.8.0"

neptune = { version = "5.1.0", optional = true, features = ["arity2", "arity4", "arity8", "arity11", "arity16", "arity24", "arity36"] }
pasta_curves = "0.3.0"
# neptune = { version = "5.1.0", optional = true, features = ["arity2", "arity4", "arity8", "arity11", "arity16", "arity24", "arity36"] }
# pasta_curves = "0.3.0"
neptune = { git = "https://github.com/filecoin-project/neptune", branch = "wip-fr-as-trait", optional = true, features = ["arity2", "arity4", "arity8", "arity11", "arity16", "arity24", "arity36"] }
pasta_curves = { git = "https://github.com/vmx/pasta_curves", branch = "ec-gpu", features = ["gpu"] }
lazy_static = { version = "1.4.0", optional = true }
blake2s_simd = { version = "0.5.11", optional = true }
sha2 = { version = "0.9.2", optional = true }
Expand Down
25 changes: 0 additions & 25 deletions filecoin-hashers/src/blake2s.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,31 +80,6 @@ impl Into<Fq> for Blake2sDomain<Fq> {
}
}

// Currently, these panics serve as a stopgap to prevent accidental conversions of a Pasta field
// domains to/from a BLS12-381 scalar field domain.
impl From<Fr> for Blake2sDomain<Fp> {
fn from(_f: Fr) -> Self {
panic!("cannot convert BLS12-381 scalar into Blake2sDomain<Fp>")
}
}
#[allow(clippy::from_over_into)]
impl Into<Fr> for Blake2sDomain<Fq> {
fn into(self) -> Fr {
panic!("cannot convert Blake2sDomain<Fq> into BLS12-381 scalar");
}
}
impl From<Fr> for Blake2sDomain<Fq> {
fn from(_f: Fr) -> Self {
panic!("cannot convert BLS12-381 scalar into Blake2sDomain<Fq>")
}
}
#[allow(clippy::from_over_into)]
impl Into<Fr> for Blake2sDomain<Fp> {
fn into(self) -> Fr {
panic!("cannot convert Blake2sDomain<Fp> into BLS12-381 scalar");
}
}

impl<F> From<[u8; 32]> for Blake2sDomain<F> {
fn from(bytes: [u8; 32]) -> Self {
Blake2sDomain {
Expand Down
31 changes: 3 additions & 28 deletions filecoin-hashers/src/poseidon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,31 +76,6 @@ impl Into<Fq> for PoseidonDomain<Fq> {
}
}

// Currently, these panics serve as a stopgap to prevent accidental conversions of a Pasta field
// domains to/from a BLS12-381 scalar field domain.
impl From<Fr> for PoseidonDomain<Fp> {
fn from(_f: Fr) -> Self {
panic!("cannot convert BLS12-381 scalar into PoseidonDomain<Fp>")
}
}
#[allow(clippy::from_over_into)]
impl Into<Fr> for PoseidonDomain<Fp> {
fn into(self) -> Fr {
panic!("cannot convert PoseidonDomain<Fp> into BLS12-381 scalar");
}
}
impl From<Fr> for PoseidonDomain<Fq> {
fn from(_f: Fr) -> Self {
panic!("cannot convert BLS12-381 scalar into PoseidonDomain<Fq>")
}
}
#[allow(clippy::from_over_into)]
impl Into<Fr> for PoseidonDomain<Fq> {
fn into(self) -> Fr {
panic!("cannot convert PoseidonDomain<Fq> into BLS12-381 scalar");
}
}

impl<F> From<[u8; 32]> for PoseidonDomain<F> {
fn from(bytes: [u8; 32]) -> Self {
PoseidonDomain {
Expand Down Expand Up @@ -377,7 +352,7 @@ impl HashFunction<PoseidonDomain<Fr>> for PoseidonFunction<Fr> {
Self::hash2_circuit(cs, left, right)
}

fn hash_multi_leaf_circuit<Arity: 'static + PoseidonArity, CS: ConstraintSystem<Fr>>(
fn hash_multi_leaf_circuit<Arity: PoseidonArity<Fr>, CS: ConstraintSystem<Fr>>(
cs: CS,
leaves: &[AllocatedNum<Fr>],
_height: usize,
Expand Down Expand Up @@ -497,7 +472,7 @@ impl HashFunction<PoseidonDomain<Fp>> for PoseidonFunction<Fp> {
unimplemented!("PoseidonFunction<Fp> cannot be used within Groth16 circuits")
}

fn hash_multi_leaf_circuit<Arity: 'static + PoseidonArity, CS: ConstraintSystem<Fr>>(
fn hash_multi_leaf_circuit<Arity: PoseidonArity<Fr>, CS: ConstraintSystem<Fr>>(
_cs: CS,
_leaves: &[AllocatedNum<Fr>],
_height: usize,
Expand Down Expand Up @@ -584,7 +559,7 @@ impl HashFunction<PoseidonDomain<Fq>> for PoseidonFunction<Fq> {
unimplemented!("PoseidonFunction<Fq> cannot be used within Groth16 circuits")
}

fn hash_multi_leaf_circuit<Arity: 'static + PoseidonArity, CS: ConstraintSystem<Fr>>(
fn hash_multi_leaf_circuit<Arity: PoseidonArity<Fr>, CS: ConstraintSystem<Fr>>(
_cs: CS,
_leaves: &[AllocatedNum<Fr>],
_height: usize,
Expand Down
66 changes: 14 additions & 52 deletions filecoin-hashers/src/poseidon_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,63 +76,25 @@ lazy_static! {
pub struct FieldArity<F, A>(PhantomData<(F, A)>)
where
F: PrimeField,
A: Arity<F>;
A: PoseidonArity<F>;

impl<F, A> typemap::Key for FieldArity<F, A>
where
F: PrimeField,
A: Arity<F>,
A: PoseidonArity<F>,
{
type Value = &'static PoseidonConstants<F, A>;
}

pub trait PoseidonArity: Arity<Fr> + Send + Sync + Clone + Debug {
#[allow(non_snake_case)]
fn PARAMETERS() -> &'static PoseidonConstants<Fr, Self>;
}

impl PoseidonArity for U0 {
fn PARAMETERS() -> &'static PoseidonConstants<Fr, Self> {
unreachable!("dummy implementation, do not ever call me")
}
}

impl PoseidonArity for U2 {
fn PARAMETERS() -> &'static PoseidonConstants<Fr, Self> {
&*POSEIDON_CONSTANTS_2
}
}

impl PoseidonArity for U4 {
fn PARAMETERS() -> &'static PoseidonConstants<Fr, Self> {
&*POSEIDON_CONSTANTS_4
}
}

impl PoseidonArity for U8 {
fn PARAMETERS() -> &'static PoseidonConstants<Fr, Self> {
&*POSEIDON_CONSTANTS_8
}
}

impl PoseidonArity for U11 {
fn PARAMETERS() -> &'static PoseidonConstants<Fr, Self> {
&*POSEIDON_CONSTANTS_11
}
}

impl PoseidonArity for U16 {
fn PARAMETERS() -> &'static PoseidonConstants<Fr, Self> {
&*POSEIDON_CONSTANTS_16
}
}
impl PoseidonArity for U24 {
fn PARAMETERS() -> &'static PoseidonConstants<Fr, Self> {
&*POSEIDON_CONSTANTS_24
}
}
impl PoseidonArity for U36 {
fn PARAMETERS() -> &'static PoseidonConstants<Fr, Self> {
&*POSEIDON_CONSTANTS_36
}
}
// A marker trait for arities which are in `POSEIDON_CONSTANTS`; we require that 'PoseidonArity<F>`
// implements `Send + Sync` because those traits are required by `lazy_static`.
pub trait PoseidonArity<F: PrimeField>: Arity<F> + Send + Sync + Clone + Debug {}

// We must implement `PoseidonArity<F> for U0` because the `U0` arity is used in compound trees
// (each compound tree arity must implement `PoseidonArity`).
impl<F: PrimeField> PoseidonArity<F> for U0 {}
impl<F: PrimeField> PoseidonArity<F> for U2 {}
impl<F: PrimeField> PoseidonArity<F> for U4 {}
impl<F: PrimeField> PoseidonArity<F> for U8 {}
impl<F: PrimeField> PoseidonArity<F> for U11 {}
impl<F: PrimeField> PoseidonArity<F> for PoseidonMDArity {}
25 changes: 0 additions & 25 deletions filecoin-hashers/src/sha256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,31 +78,6 @@ impl Into<Fq> for Sha256Domain<Fq> {
}
}

// Currently, these panics serve as a stopgap to prevent accidental conversions of a Pasta field
// domains to/from a BLS12-381 scalar field domain.
impl From<Fr> for Sha256Domain<Fp> {
fn from(_f: Fr) -> Self {
panic!("cannot convert BLS12-381 scalar into Sha256Domain<Fp>")
}
}
#[allow(clippy::from_over_into)]
impl Into<Fr> for Sha256Domain<Fp> {
fn into(self) -> Fr {
panic!("cannot convert Sha256Domain<Fp> into BLS12-381 scalar");
}
}
impl From<Fr> for Sha256Domain<Fq> {
fn from(_f: Fr) -> Self {
panic!("cannot convert BLS12-381 scalar into Sha256Domain<Fq>")
}
}
#[allow(clippy::from_over_into)]
impl Into<Fr> for Sha256Domain<Fq> {
fn into(self) -> Fr {
panic!("cannot convert Sha256Domain<Fq> into BLS12-381 scalar");
}
}

impl<F> From<[u8; 32]> for Sha256Domain<F> {
fn from(bytes: [u8; 32]) -> Self {
Sha256Domain {
Expand Down
14 changes: 3 additions & 11 deletions filecoin-hashers/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use bellperson::{
ConstraintSystem, SynthesisError,
};
use blstrs::Scalar as Fr;
use ec_gpu::GpuField;
use ff::{Field, PrimeField};
use merkletree::{
hash::{Algorithm as LightAlgorithm, Hashable as LightHashable},
Expand All @@ -28,15 +29,6 @@ pub trait Domain:
+ Eq
+ Send
+ Sync
// TODO (halo): remove once we have Pasta GPU support.
// Currently the `From<Fr> + Into<Fr>` trait bounds are used as a stopgap to prevent
// Pasta field domains from being used in GPU code, e.g. currently converting a
// `Sha256Domain<Fp>` into an `Fr` panics. Remove theses trait bounds once Pasta fields are
// fully supported in `rust-fil-proofs`, e.g. GPU code.
+ From<Fr>
+ Into<Fr>
// Note that `Self::Field` may be `Fr`, in which case the trait bounds
// `From<Self::Field> + Into<Self::Field>` are redundant.
+ From<Self::Field>
+ Into<Self::Field>
+ From<[u8; 32]>
Expand All @@ -45,7 +37,7 @@ pub trait Domain:
+ Element
+ StdHash
{
type Field: PrimeField;
type Field: PrimeField + GpuField;

#[allow(clippy::wrong_self_convention)]
fn into_bytes(&self) -> Vec<u8> {
Expand Down Expand Up @@ -110,7 +102,7 @@ pub trait HashFunction<T: Domain>: Clone + Debug + Send + Sync + LightAlgorithm<
Self::hash_leaf_bits_circuit(cs, &left_bits, &right_bits, height)
}

fn hash_multi_leaf_circuit<Arity: 'static + PoseidonArity, CS: ConstraintSystem<Fr>>(
fn hash_multi_leaf_circuit<Arity: PoseidonArity<Fr>, CS: ConstraintSystem<Fr>>(
cs: CS,
leaves: &[AllocatedNum<Fr>],
height: usize,
Expand Down
17 changes: 8 additions & 9 deletions filecoin-proofs/src/api/util.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
use std::mem::size_of;

use anyhow::{Context, Result};
use blstrs::Scalar as Fr;
use ff::PrimeField;
use filecoin_hashers::{Domain, Hasher};
use fr32::{bytes_into_fr, fr_into_bytes};
use merkletree::merkle::{get_merkle_tree_leafs, get_merkle_tree_len};
use storage_proofs_core::merkle::{get_base_tree_count, MerkleTreeTrait};
use typenum::Unsigned;

use crate::types::{Commitment, SectorSize};

pub fn as_safe_commitment<H: Domain, T: AsRef<str>>(
pub fn as_safe_commitment<D: Domain, T: AsRef<str>>(
comm: &[u8; 32],
commitment_name: T,
) -> Result<H> {
bytes_into_fr(comm)
) -> Result<D> {
let mut repr = <D::Field as PrimeField>::Repr::default();
repr.as_mut().copy_from_slice(comm);
D::Field::from_repr_vartime(repr)
.map(Into::into)
.with_context(|| format!("Invalid commitment ({})", commitment_name.as_ref(),))
}

pub fn commitment_from_fr(fr: Fr) -> Commitment {
pub fn commitment_from_fr<F: PrimeField>(fr: F) -> Commitment {
let mut commitment = [0; 32];
for (i, b) in fr_into_bytes(&fr).iter().enumerate() {
commitment[i] = *b;
}
commitment.copy_from_slice(fr.to_repr().as_ref());
commitment
}

Expand Down
3 changes: 2 additions & 1 deletion fr32/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ blstrs = "0.4.0"
bitvec = "0.17"
criterion = "0.3"
itertools = "0.9"
pasta_curves = "0.3.0"
# pasta_curves = "0.3.0"
pasta_curves = { git = "https://github.com/vmx/pasta_curves", branch = "ec-gpu", features = ["gpu"] }
pretty_assertions = "0.6.1"
rand = "0.8"
rand_xorshift = "0.3"
Expand Down
6 changes: 4 additions & 2 deletions storage-proofs-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ hex = "0.4.0"
generic-array = "0.14.4"
anyhow = "1.0.23"
thiserror = "1.0.6"
neptune = { version = "5.1.0", features = ["arity2", "arity4", "arity8", "arity11", "arity16", "arity24", "arity36"] }
# neptune = { version = "5.1.0", features = ["arity2", "arity4", "arity8", "arity11", "arity16", "arity24", "arity36"] }
neptune = { git = "https://github.com/filecoin-project/neptune", branch = "wip-fr-as-trait", optional = true, features = ["arity2", "arity4", "arity8", "arity11", "arity16", "arity24", "arity36"] }
cpu-time = { version = "1.0", optional = true }
gperftools = { version = "0.2", optional = true }
num_cpus = "1.10.1"
Expand All @@ -56,7 +57,8 @@ rand_xorshift = "0.3.0"
pretty_assertions = "0.6.1"
sha2raw = { path = "../sha2raw", version = "^6.0.0"}
filecoin-hashers = { path = "../filecoin-hashers", version = "^6.0.0", default-features = false, features = ["blake2s", "sha256", "poseidon"] }
pasta_curves = "0.3.0"
# pasta_curves = "0.3.0"
pasta_curves = { git = "https://github.com/vmx/pasta_curves", branch = "ec-gpu", features = ["gpu"] }

[features]
default = ["opencl"]
Expand Down
12 changes: 6 additions & 6 deletions storage-proofs-core/src/crypto/sloth.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
use blstrs::Scalar as Fr;
use ff::PrimeField;

/// Sloth based encoding.
#[inline]
pub fn encode(key: &Fr, plaintext: &Fr) -> Fr {
plaintext + key
pub fn encode<F: PrimeField>(key: &F, plaintext: &F) -> F {
*plaintext + *key
}

/// Sloth based decoding.
#[inline]
pub fn decode(key: &Fr, ciphertext: &Fr) -> Fr {
ciphertext - key
pub fn decode<F: PrimeField>(key: &F, ciphertext: &F) -> F {
*ciphertext - *key
}

#[cfg(test)]
mod tests {
use super::*;

use ff::PrimeField;
use blstrs::Scalar as Fr;
use proptest::{prop_compose, proptest};

// the modulus from `bls12_381::Fr`
Expand Down
13 changes: 10 additions & 3 deletions storage-proofs-core/src/drgraph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::fmt::Debug;
use std::marker::PhantomData;

use anyhow::ensure;
use filecoin_hashers::{Hasher, PoseidonArity};
use filecoin_hashers::{Domain, Hasher, PoseidonArity};
use fr32::bytes_into_fr_repr_safe;
use generic_array::typenum::Unsigned;
use merkletree::merkle::get_merkle_tree_row_count;
Expand Down Expand Up @@ -37,7 +37,10 @@ pub trait Graph<H: Hasher>: Debug + Clone + PartialEq + Eq {
}

/// Returns the merkle tree depth.
fn merkle_tree_depth<U: 'static + PoseidonArity>(&self) -> u64 {
fn merkle_tree_depth<U>(&self) -> u64
where
U: PoseidonArity<<H::Domain as Domain>::Field>,
{
graph_height::<U>(self.size()) as u64
}

Expand Down Expand Up @@ -365,7 +368,11 @@ mod tests {
graph_bucket::<Blake2sHasher<Fq>>();
}

fn gen_proof<H: 'static + Hasher, U: 'static + PoseidonArity>(config: Option<StoreConfig>) {
fn gen_proof<H, U>(config: Option<StoreConfig>)
where
H: 'static + Hasher,
U: PoseidonArity<<H::Domain as Domain>::Field>,
{
let leafs = 64;
let porep_id = [1; 32];
let g = BucketGraph::<H>::new(leafs, BASE_DEGREE, 0, porep_id, ApiVersion::V1_1_0)
Expand Down
Loading

0 comments on commit 952341e

Please sign in to comment.