-
Notifications
You must be signed in to change notification settings - Fork 25
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
Allow addition and multiplication for references to secret shared values #787
Conversation
New trait bounds for arithmetic but getting the following error overflow evaluating the requirement `&ordered_float::OrderedFloat<_>: Neg` I guess I need to constrain that type to `Linear`
If this plane did not have a WiFi, I'd never be able to do it. It seems that `Neg` was tripping me off - adding it as a constraint to trait <A, B> and only constraining it to B, makes the compiler go to infinite loop trying to evaluate all possible types that can fit. At the end, I was getting the gnarly "overflow evaluating ..." error So structure needs to be as follows: * Traits that have Rhs and Output * Traits that only have Output * Traits that are valid for secret sharing (add, sub, neg) * Traits that are valid for basic arithmetic (mul)
Add new trait bound to fix it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some clarity about naming is probably worth trying to achieve.
src/ff/mod.rs
Outdated
/// | ||
/// [`RefNum`]: https://docs.rs/num/0.4.1/num/traits/trait.RefNum.html | ||
/// [`rust-issue`]: https://github.com/rust-lang/rust/issues/20671 | ||
pub trait RefOps<'a, Base: 'a, R: 'a>: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that ArithmeticOps
is the better choice of name here, with the trait above being for ArithmeticAssignOps
or something like that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd love to keep Ref
somewhere in the name to indicate that it only makes sense to implement/bound if you need l-value references
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ArithmeticRefOps
then, I guess.
src/ff/mod.rs
Outdated
pub trait LocalAssignOps<Rhs = Self>: AddAssign<Rhs> + SubAssign<Rhs> {} | ||
impl<T, Rhs> LocalAssignOps<Rhs> for T where T: AddAssign<Rhs> + SubAssign<Rhs> {} | ||
|
||
/// Arithmetic operations that may or may not require communication. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can these really involve communication? None of these traits are async, so this can't do that. That suggests that these are still local operations, but only those that involve value-based l-values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to distinguish operations that can be safely performed locally and confusing ones like Mul
that someone can accidentally implement for secret shares as (a.0 * b.0, a.1 * b.1)
. Lets chat later today about it - I'd love to have better names for all of those traits
src/protocol/basics/if_else.rs
Outdated
@@ -30,6 +31,6 @@ where | |||
// = false_value | |||
Ok(false_value.clone() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missed a clone opportunity?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh my...
src/ff/mod.rs
Outdated
/// Note: Neg operation is also local, but is causing issues when added as a bound to this trait. | ||
/// The problem is that it does not use `Rhs` generic and rustc overflows trying to compile functions | ||
/// that use HRTB generics bounded by `LocalArithmeticOps`. | ||
pub trait LocalArithmeticOps<Rhs = Self, Output = Self>: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
addsub?
thanks to mt@'s eagle eye vision.
It is too specific to be in the finite fields, basically nothing except `Linear` can conform to it
and rename RefOps to `LinearRefOps`
@martinthomson I think it is ready for review now |
This change brings an extra trait bound for linear secret sharing trait, to allow addition and multiplication on references, rather than owned types. Currently it is only possible to do
a + b
ora + &b
, but not&a + b
or&a + &b
. This change makes it possible.As usual, it is not all rosy here, because of the compiler issue: rust-lang/rust#20671. There is a need currently to specify the additional trait bound on every function, but I think it is worth it because not every
.clone()
call can be eliminated by the compiler, as it can be seen here. We're better off helping optimizer here. So it cost us additional trait bound, but gives a much nicer addition/multiplication w/o extra clones and makes us not worry about compiler not being able to optimize it.Once (if?) that gnarly issue is fixed, we could probably just add
for <'a, 'b> &'a Self: Add<'b Self>
bound toArithmeticOps
trait and eliminate all extra helper traits along with extra bounds on functions.Implementation notes
I could've probably used a macro to synthesize all extra
Add
/Sub
/Mul
implementations, but decided it is not worth it for just two types. Maybe if we had more secret sharing types ....I tried hard to mimic
num
trait definition (Add new traits for reference and assignment operators rust-num/num#283), but ran into an error complaining thatAdd
operation is not general enough:it remains a mystery to me, why I was getting it. The same function worked just fine for
u32
and primitive types had the same 4Add
overloads with reference ones defined exactly as ours for additive secret shares.