-
Notifications
You must be signed in to change notification settings - Fork 75
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
Zero Knowledge Proof #2
Conversation
Test: cargo build & cargo test
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.
Looking good overall with a few comments below!
Regarding the proofs, I think we should:
- rename traits to something more descriptive to account for supporting several proofs
- combine prover and verifier functions in same trait
- worry about abstract proof traits later
- use specific types to wrap challenges and proofs
For instance, I'm adding something along the lines of ProveCorrectDecryption
:
pub struct CorrectDecryptionProof { ... };
pub trait ProveCorrectDecryption {
fn prove(...) -> CorrectDecryptionProof;
fn verify(CorrectDecryptionProof, ...) -> Result<...>;
}
Also, I'm keeping with the idea of implementing everything on the Paillier
struct as opposed to EncryptionKey
and DecryptionKey
-- it makes sense to also expose some of the operations on the latter objects (including Add
and Mul
on ciphertexts) but would like to keep things consistent until then.
Finally, many of the while
loops could be replaced with more rust-like constructions (to reduce bugs and make the code look less like C)
src/arithimpl/gmpimpl.rs
Outdated
@@ -45,6 +45,15 @@ impl ModPow for Mpz { | |||
} | |||
} | |||
|
|||
impl ModMul for Mpz { | |||
fn modmul(base: &Self, exponent: &Self, modulus: &Self) -> 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.
not entirely sure I understand why this is needed as opposed to just doing a modulus reduction? in any case, the base
and exponent
arguments should probably be renamed
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.
@mortendahl :
This is supposed to be : (A * B) mod C = (A mod C * B mod C) mod C .
It is used for example here: M′=MQ+Q((Q−1modP)(MP−MQ)modP).
@gbenattar : base and exponent should be renamed.
@@ -80,6 +81,7 @@ where | |||
let cp = I::modpow(&c.0, &dk.pminusone, &dk.pp); | |||
let lp = l(&cp, &dk.p); | |||
let mp = (&lp * &dk.hp) % &dk.p; | |||
|
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.
no changes here?
src/traits.rs
Outdated
@@ -1,5 +1,6 @@ | |||
|
|||
//! Abstract operations exposed by the library. | |||
pub const ZK_SECURITY_FACTOR : usize = 40; |
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.
move this closer to where it's used?
src/core/crt.rs
Outdated
} | ||
|
||
impl<I> ZKProver<I> for DecryptionKey<I> | ||
where |
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.
(all these bounds will go away in the upcoming simplification 🎉)
src/arithimpl/traits.rs
Outdated
} | ||
|
||
pub trait FromString<I> { | ||
fn from_hex_str(a: String) -> 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.
&str
instead of String
?
src/zkproof/mod.rs
Outdated
let mut i : usize = 0; | ||
while i < ZK_SECURITY_FACTOR { | ||
let candidate = I::sample_below(&self.n); | ||
if I::egcd(&self.n, &candidate).0 != I::one() { continue; } |
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 check could be skipped without any practical impact as far as can I see (if gcd != 1 you managed to factor n
). would also allow some simplification of the code.
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 agree.
src/zkproof/mod.rs
Outdated
for<'a> &'a I: Mul<I, Output=I>, | ||
{ | ||
fn generate_challenge(&self) -> (Vec<I>, I, Vec<I>, Vec<I>) { | ||
let (mut y, mut challenge) : (Vec<I>, Vec<I>) = (Vec::new(), Vec::new()); |
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.
could take advantage of the fact that we know the final size of the vectors in advance (unless simplified as mentioned below)
I'd be interested in trying out Any thoughts on this? |
Hi, The new trait is (part of its own file): pub struct CorrectInputProof<I> {
pub e : I,
pub z : Vec<I>,
}
pub struct CorrectKeyProof<I> {
pub proof : I,
}
pub trait ProveCorrectKey<I, EK, DK> {
fn generate_challenge(ek: &EK) -> (Vec<I>, CorrectInputProof<I>, Vec<I>);
fn prove(dk: &DK, challenge: &Vec<I>, correct_input_proof: &CorrectInputProof<I>)
-> Result<CorrectKeyProof<I>, ProofError>;
fn verify(correct_key_proof: &CorrectKeyProof<I>, y: &Vec<I>) -> Result<(), ProofError>;
} |
Changing base branch to dev as requested by @mortendahl. |
In the last commit, I switched from |
See snipsco/rust-paillier#29
Test: cargo build & cargo test