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

implement bls12-381 functions #1345

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open

implement bls12-381 functions #1345

wants to merge 8 commits into from

Conversation

jayz22
Copy link
Contributor

@jayz22 jayz22 commented Sep 19, 2024

Corresponding env change: stellar/rs-soroban-env#1456

bump protocol_version locally

add basic g1/g2_add test

expose dst

add mult-pairing-check

update scalar to use U256 representation

update env

update env pick up xdr change

bump sdk version

implement bls12-381
Cargo.toml Outdated Show resolved Hide resolved
soroban-sdk/src/crypto.rs Outdated Show resolved Hide resolved
soroban-sdk/src/crypto.rs Outdated Show resolved Hide resolved
soroban-sdk/src/crypto.rs Outdated Show resolved Hide resolved
let env = self.env();
let bin = internal::Env::bls12_381_g1_add(env, p0.to_object(), p1.to_object())
.unwrap_infallible();
G1Affine::from_bytes(bin.try_into_val(env).unwrap_optimized())
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Could try_into_val.unwrap be just into_val?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

Copy link
Member

Choose a reason for hiding this comment

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

We should be able to do this with an unchecked op if we know for sure bin is always of the correct size. We do that in some areas of the SDK.

soroban-sdk/src/crypto.rs Outdated Show resolved Hide resolved
soroban-sdk/src/tests/crypto_bls12_381.rs Show resolved Hide resolved
Copy link
Contributor

@dmkozh dmkozh left a comment

Choose a reason for hiding this comment

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

LGTM for now, I think we can clean up the 'namespacing' and add more tests as a followup.

soroban-sdk/src/crypto.rs Outdated Show resolved Hide resolved
Copy link
Member

@leighmcculloch leighmcculloch left a comment

Choose a reason for hiding this comment

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

Few comments inline.

soroban-sdk/src/crypto.rs Outdated Show resolved Hide resolved
env: Env,
}

/// # `G1Affine` is a point in the G1 group (subgroup defined over the base field
Copy link
Member

Choose a reason for hiding this comment

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

It's not common to make the first line of these doc comments a heading. Is there a reason we need it to be?

Suggested change
/// # `G1Affine` is a point in the G1 group (subgroup defined over the base field
/// `G1Affine` is a point in the G1 group (subgroup defined over the base field

Comment on lines 337 to 339
// #[derive(Clone)]
// #[repr(transparent)]
// pub struct $elem(BytesN<$size>);
Copy link
Member

Choose a reason for hiding this comment

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

?

Copy link
Contributor

Choose a reason for hiding this comment

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

Removed

#[repr(transparent)]
pub struct Fp2(BytesN<96>);

macro_rules! impl_bls_elements_bytes_repr {
Copy link
Member

Choose a reason for hiding this comment

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

This looks useful for types that wrap BytesN in general. Could we move this macro into the bytes file and name it something like impl_bytesn_repr?

Copy link
Contributor

Choose a reason for hiding this comment

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

Done

}

/// Adds two points `p0` and `p1` in G1.
pub fn g1_add(&self, p0: &G1Affine, p1: &G1Affine) -> G1Affine {
Copy link
Member

Choose a reason for hiding this comment

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

It looks like most of the functions on the Bls12_381 type orient around the bls types. For example, this one here g1_add could be a function on g1.

In general I quite like these style of APIs where modules contain the functionality and types are just data.

However it introduces some awkwardness when writing contracts.

If a developer writes code that uses the G1, or other, types, then they might be passing them around. If all the operations are on the env, they need to get the env either from the G1 or by passing it around too. In rust docs it also becomes harder to discover all the operations that can be done on a g1, g2, etc.

For some the operations, like add, we can impl the core lib's traits, e.g. Add.

fn do_things(a: G1Affine, b: G1Affine) /* -> ... */ {
    let c = a.env().crypto().bls12_381().g1_add(a, b);
    // ...
}

vs

fn do_things(a: G1Affine, b: G1Affine) /* -> ... */ {
    let c = a.add(b);
    // ...
}

Comment on lines 423 to 424
write!(f, "{}({:?})", $name, self.to_array())?;
Ok(())
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't need the branch return then okay.

Suggested change
write!(f, "{}({:?})", $name, self.to_array())?;
Ok(())
write!(f, "{}({:?})", $name, self.to_array())

Copy link
Contributor

Choose a reason for hiding this comment

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

Done

soroban-sdk/src/crypto.rs Outdated Show resolved Hide resolved
.into();
match is_in_correct_subgroup {
true => res,
false => panic!("result G1 point not in the correct subgroup"),
Copy link
Member

Choose a reason for hiding this comment

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

We shouldn't ever use panic! in the SDK. It'll introduce text into the .wasm builds. In any case I think it'll go away when we switch to returning an Option.

Copy link
Member

Choose a reason for hiding this comment

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

Use the sdk_panic! macro, it's an internal macro that'll remove the text in the wasm build.

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like Jay addressed this

Comment on lines 318 to 321
#[inline(always)]
pub fn bls12_381(&self) -> Bls12_381 {
Bls12_381::new(self)
}
Copy link
Member

Choose a reason for hiding this comment

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

Given this is crypto, it should I think be accessible on the .crypto() fn instead of at the top-level.

Suggested change
#[inline(always)]
pub fn bls12_381(&self) -> Bls12_381 {
Bls12_381::new(self)
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Done


/// Bls12_381 provides access to curve and field arithmetics on the BLS12-381
/// curve.
pub struct Bls12_381 {
Copy link
Member

Choose a reason for hiding this comment

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

Can we put this type and all the subtypes in a module under crypto? There's quite a lot being added and the organisation would be helpful I think.

Copy link
Contributor

Choose a reason for hiding this comment

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

Are you saying we should create a crypto directory to organize the crypto related modules?

Copy link
Member

Choose a reason for hiding this comment

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

We don't need to refactor all the existing code, just yeah make a crypto directory and put the new bls code in a bls12_318.rs file.

Copy link
Contributor

Choose a reason for hiding this comment

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

done

@@ -244,6 +244,8 @@ deny = [
# Certain crates/versions that will be skipped when doing duplicate detection.
skip = [
#{ name = "ansi_term", version = "=0.11.0" },
{ name = "hashbrown", version = "=0.14.5" },
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this change should be fine... but I'm highlighting this so it isn't missed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants