-
Notifications
You must be signed in to change notification settings - Fork 10
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
Share recovery and refreshing #26
Conversation
tpke/src/lib.rs
Outdated
@@ -140,7 +136,7 @@ pub fn setup<E: PairingEngine>( | |||
// F_0 - The commitment to the constant term, and is the public key output Y from PVDKG | |||
// TODO: It seems like the rest of the F_i are not computed? | |||
let pubkey = g.mul(x); | |||
let privkey = h.mul(x); | |||
let privkey = h.mul(x); // ek_i in PVSS? |
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.
let privkey = h.mul(x); // ek_i in PVSS? | |
let privkey = h.mul(x); |
No, this is the private key share, which is different from the protocol-level "private key" (which can be very confusing). Let's call ek_i
the (private) blinding key.
tpke/src/lib.rs
Outdated
checked_decrypt_with_shared_secret(&ciphertext, aad, &shared_secret) | ||
}); | ||
assert!(result.is_err()); | ||
} | ||
|
||
#[test] | ||
fn simple_threshold_decryption_with_share_refreshing_at_point() { |
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 the name "share refresh" here is confusing. We need to agree on a naming convention. Let's assume N
is the original number of shares, and t
is the threshold. There are 2 different types of share calculation protocols, used in 3 different ways:
Ñ
parties (wheret <= Ñ <= N
) jointly execute a "share refresh" or "share renewal" algorithm, and the output isM
new shares (withM <= Ñ
), with each of theM
new shares substituting the original share (i.e., the original share is deleted). I personally like "share refresh" but the original paper calls it "share renewal" (also fine).Ñ
parties (wheret <= Ñ <= N
) jointly execute a "share recovery" algorithm, and the output is 1 new share. There are 2 potential variants here:
2.1. The new share is intended to restore a previously existing share, e.g., due to loss or corruption. It could also be used to on-board a new participant but reusing a previously existing share (sounds like a bad idea, though)
2.2. The new share is independent from the previously existing shares. We can use this to on-board a new participant into an existing cohort.
In this test, you're actually doing 2.1, but the name "share refresh" is confusing to me. Let's settle in a convention for naming algorithms 1, 2.1 and 2.2 and use it consistently.
tpke/src/refresh.rs
Outdated
d_i | ||
} | ||
|
||
fn evaluate_polynomial<E: PairingEngine>( |
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.
Maybe there's an arkworks method for this.
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.
looks like there is https://github.com/arkworks-rs/algebra/tree/master/poly
tpke/src/refresh.rs
Outdated
let i = p.index; | ||
let x_i = p.public_decryption_contexts[i].domain; | ||
let eval = evaluate_polynomial::<E>(coeffs, &x_i); | ||
let h_g2 = E::G2Projective::from(p.h); |
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.
This could be taken outside of the loop, or even moved to a public context, since it's just the H generator in projective representation.
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.
In tpke
, public context corresponds to variables shared with other participants, and since they already have h
there is no reason to put it there.
The different structs in tpke
are going to be refactored so that should bring a bit more clarity.
tpke/src/lib.rs
Outdated
@@ -269,6 +265,7 @@ pub fn setup_simple<E: PairingEngine>( | |||
g, | |||
g_inv: E::G1Prepared::from(-g), | |||
h_inv: E::G2Prepared::from(-h), | |||
h, // TODO: Remove this sensitive data here |
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.
What sensitive data?
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.
It's a left-over TODO. h
is just a G2 generator, so it's not sensitive. I didn't know any better when I wrote it, sorry about the confusion.
tpke/src/lib.rs
Outdated
p.public_decryption_contexts.pop(); | ||
} | ||
|
||
// Refresh the share |
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.
See comment above wrt to naming convention. The method here is called share recovery but the comment here says refresh.
let recovered_key_share = PrivateKeyShare { | ||
private_key_shares: vec![y_r.into_affine()], | ||
}; | ||
|
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.
We don't need to create decryption shares and encryption/decryption. We can simply reconstruct the original secret before and after. To do so, we just need to get the context.private_key_share
elements and combine them with the proper lagrange coefficients.
make_decryption_share(&private_share, &ciphertext) | ||
}) | ||
.collect(); | ||
|
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.
Same as above. After the share refreshing algorithm, the shared secret should remain the same.
tpke/src/lib.rs
Outdated
.collect::<Vec<_>>(); | ||
let lagrange = prepare_combine_simple::<E>(shares_x); | ||
|
||
let shared_secret = |
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.
This name is confusing. The ferveo paper call this ephemeral shared secret
, but I think the word "shared" is misleading and doesn't add anything. Let's rename this to ephemeral secret
.
This is important to avoid confusion with the real shared secret (i.e. the distributed secret after the DKG protocol)
let i = p.index; | ||
let mut new_y = E::G2Projective::from( | ||
p.private_key_share.private_key_shares[0], // y_i | ||
); |
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.
Why they need to be converted into Projective form?
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.
In arkworks
, Projective
form is preferred since it "is generally more efficient for arithmetic". The PrivateKeyShares
are G2Affine
and so we convert to it later on.
dcc095d
to
3c6a9a2
Compare
3c6a9a2
to
989415a
Compare
tpke/src/lib.rs
that contain three different PSS flows:simple_threshold_decryption_with_share_refreshing_at_point
- refreshes a key share knowing the evaluation point of a selected PSS participantsimple_threshold_decryption_with_share_recovery_at_point
- recovers a key share with no knowledge of the evaluation point of a selected participant. Effectively, we generate a new key share for a new participant. Uses the same implementation as the previous test (section 4.2)simple_threshold_decryption_with_share_refresh
- refreshes all key shares for all existing participants. Uses a slightly different approach than the previous implementationstpke/src/refresh.rs