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

Padding point gen using Try-And-Increment #32

Merged
merged 8 commits into from
Sep 20, 2024
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
6 changes: 2 additions & 4 deletions ring/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ ark-bls12-381 = { version = "0.4", default-features = false, features = ["curve"
ark-ed-on-bls12-381-bandersnatch = { version = "0.4", default-features = false }

[features]
default = []
default = [ "std" ]
std = [
"ark-std/std",
"ark-ff/std",
Expand All @@ -49,6 +49,4 @@ print-trace = [
"ark-std/print-trace",
"common/print-trace"
]
asm = [
"fflonk/asm"
]
asm = [ "fflonk/asm" ]
26 changes: 16 additions & 10 deletions ring/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
#![cfg_attr(not(feature = "std"), no_std)]

use ark_ec::AffineRepr;
use ark_ec::short_weierstrass::{Affine, SWCurveConfig};
use ark_ec::{short_weierstrass::{Affine, SWCurveConfig}, AffineRepr};
use ark_ff::{One, PrimeField, Zero};
use ark_serialize::CanonicalSerialize;
use ark_std::rand;
use ark_std::rand::RngCore;
use fflonk::pcs::PCS;

Expand Down Expand Up @@ -37,14 +35,22 @@ pub fn find_complement_point<Curve: SWCurveConfig>() -> Affine<Curve> {
}
}

// TODO: switch to better hash to curve when available
pub fn hash_to_curve<A: AffineRepr>(message: &[u8]) -> A {
// Try and increment hash to curve.
pub(crate) fn hash_to_curve<F: PrimeField, Curve: SWCurveConfig<BaseField = F>>(message: &[u8]) -> Affine<Curve> {
use blake2::Digest;
use ark_std::rand::SeedableRng;

let seed = blake2::Blake2s::digest(message);
let rng = &mut rand::rngs::StdRng::from_seed(seed.into());
A::rand(rng)
let mut seed = message.to_vec();
let cnt_offset = seed.len();
seed.push(0);
loop {
let hash: [u8; 64] = blake2::Blake2b::digest(&seed[..]).into();
let x = F::from_le_bytes_mod_order(&hash);
if let Some(point) = Affine::<Curve>::get_point_from_x_unchecked(x, false) {
let point = point.clear_cofactor();
Copy link
Collaborator

@swasilyev swasilyev Sep 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@burdges do we care if it is in the subgroup? Just curious.

Copy link
Collaborator Author

@davxy davxy Sep 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

he asked the same question here: #31 (review)

But I guess yes? As the SEED is not in the prime order subgroup, if you add a padding point not in the prime order subgroup you may end-up with the point at infinity right? Which is not managed in the constraints (and primarily that is why the SEED is chosen to be out of the prime subgroup).

Copy link
Collaborator

@burdges burdges Sep 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. We cannot compute x+x in the SNARK, only x+y with x != y. As our snark never checks that x != y, we need all our additions to be x != y implicitly.

We have two padding points, the start point hs and the empty point he, maybe equal. We compute (..((hs + x[0]) + x[1]) + .. + x[n]) - hs where the x[i] are either a public key if in the bitfield, or zero=infinity if not in the bitfield, or he no public key exists there.

We need -2 hs to not be a combination of x[i], but n << group_order, so either hs should be outside the prime order subgroup, or else we should've proofs of possession for the public keys.

We should presumably just do proofs of possession, because that'll work for prime order curves by bn254, but if skipped the proofs of possession then he != hs matters, but hs = he + coset_element works.

assert!(point.is_in_correct_subgroup_assuming_on_curve());
return point
}
seed[cnt_offset] += 1;
}
}

#[derive(Clone)]
Expand Down
2 changes: 1 addition & 1 deletion ring/src/piop/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub struct PiopParams<F: PrimeField, Curve: SWCurveConfig<BaseField=F>> {

impl<F: PrimeField, Curve: SWCurveConfig<BaseField=F>> PiopParams<F, Curve> {
pub fn setup(domain: Domain<F>, h: Affine<Curve>, seed: Affine<Curve>) -> Self {
let padding_point = crate::hash_to_curve::<Affine<Curve>>(b"w3f/ring-proof/common/padding");
let padding_point = crate::hash_to_curve(b"/w3f/ring-proof/padding");
let scalar_bitlen = Curve::ScalarField::MODULUS_BIT_SIZE as usize;
// 1 accounts for the last cells of the points and bits columns that remain unconstrained
let keyset_part_size = domain.capacity - scalar_bitlen - 1;
Expand Down
Loading