mirror of https://github.com/zcash/mpc.git
Derive encodings of contents of public key.
This commit is contained in:
parent
2f081e231f
commit
d93139396d
|
@ -8,7 +8,10 @@ use snark::*;
|
||||||
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
|
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq)]
|
#[derive(Clone, PartialEq, Eq)]
|
||||||
pub struct PublicKey {
|
pub struct PublicKey(PublicKeyInner);
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable)]
|
||||||
|
struct PublicKeyInner {
|
||||||
f1: G2, // f1
|
f1: G2, // f1
|
||||||
f1_rho_a: G2, // f1 * rho_a
|
f1_rho_a: G2, // f1 * rho_a
|
||||||
f1_rho_a_alpha_a: G2, // f1 * rho_a * alpha_a
|
f1_rho_a_alpha_a: G2, // f1 * rho_a * alpha_a
|
||||||
|
@ -48,31 +51,31 @@ impl PublicKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn nizks_are_valid(&self) -> bool {
|
fn nizks_are_valid(&self) -> bool {
|
||||||
self.f3_tau.verify_nizk(&self.nizk_tau) &&
|
self.0.f3_tau.verify_nizk(&self.0.nizk_tau) &&
|
||||||
self.f4_alpha_a.verify_nizk(&self.nizk_alpha_a) &&
|
self.0.f4_alpha_a.verify_nizk(&self.0.nizk_alpha_a) &&
|
||||||
self.alpha_b_g2().verify_nizk(&self.nizk_alpha_b) &&
|
self.alpha_b_g2().verify_nizk(&self.0.nizk_alpha_b) &&
|
||||||
self.f5_alpha_c.verify_nizk(&self.nizk_alpha_c) &&
|
self.0.f5_alpha_c.verify_nizk(&self.0.nizk_alpha_c) &&
|
||||||
self.rho_a_g2().verify_nizk(&self.nizk_rho_a) &&
|
self.rho_a_g2().verify_nizk(&self.0.nizk_rho_a) &&
|
||||||
self.f6_rho_b.verify_nizk(&self.nizk_rho_b) &&
|
self.0.f6_rho_b.verify_nizk(&self.0.nizk_rho_b) &&
|
||||||
self.beta_g2().verify_nizk(&self.nizk_beta) &&
|
self.beta_g2().verify_nizk(&self.0.nizk_beta) &&
|
||||||
self.f8_gamma.verify_nizk(&self.nizk_gamma)
|
self.0.f8_gamma.verify_nizk(&self.0.nizk_gamma)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_well_formed(&self) -> bool {
|
fn is_well_formed(&self) -> bool {
|
||||||
!self.f1.is_zero() &&
|
!self.0.f1.is_zero() &&
|
||||||
!self.f1_rho_a.is_zero() &&
|
!self.0.f1_rho_a.is_zero() &&
|
||||||
!self.f1_rho_a_alpha_a.is_zero() &&
|
!self.0.f1_rho_a_alpha_a.is_zero() &&
|
||||||
!self.f1_rho_a_rho_b.is_zero() &&
|
!self.0.f1_rho_a_rho_b.is_zero() &&
|
||||||
!self.f1_rho_a_rho_b_alpha_c.is_zero() &&
|
!self.0.f1_rho_a_rho_b_alpha_c.is_zero() &&
|
||||||
!self.f1_rho_a_rho_b_alpha_b.is_zero() &&
|
!self.0.f1_rho_a_rho_b_alpha_b.is_zero() &&
|
||||||
!self.f2.is_zero() &&
|
!self.0.f2.is_zero() &&
|
||||||
!self.f2_beta.is_zero() &&
|
!self.0.f2_beta.is_zero() &&
|
||||||
!self.f2_beta_gamma.is_zero() &&
|
!self.0.f2_beta_gamma.is_zero() &&
|
||||||
same_power(&self.f4_alpha_a, &Spair::new(self.f1_rho_a, self.f1_rho_a_alpha_a).unwrap()) &&
|
same_power(&self.0.f4_alpha_a, &Spair::new(self.0.f1_rho_a, self.0.f1_rho_a_alpha_a).unwrap()) &&
|
||||||
same_power(&self.f5_alpha_c, &Spair::new(self.f1_rho_a_rho_b, self.f1_rho_a_rho_b_alpha_c).unwrap()) &&
|
same_power(&self.0.f5_alpha_c, &Spair::new(self.0.f1_rho_a_rho_b, self.0.f1_rho_a_rho_b_alpha_c).unwrap()) &&
|
||||||
same_power(&self.f6_rho_b, &Spair::new(self.f1_rho_a, self.f1_rho_a_rho_b).unwrap()) &&
|
same_power(&self.0.f6_rho_b, &Spair::new(self.0.f1_rho_a, self.0.f1_rho_a_rho_b).unwrap()) &&
|
||||||
same_power(&self.f7_rho_a_rho_b, &Spair::new(self.f1, self.f1_rho_a_rho_b).unwrap()) &&
|
same_power(&self.0.f7_rho_a_rho_b, &Spair::new(self.0.f1, self.0.f1_rho_a_rho_b).unwrap()) &&
|
||||||
same_power(&self.f8_gamma, &Spair::new(self.f2_beta, self.f2_beta_gamma).unwrap())
|
same_power(&self.0.f8_gamma, &Spair::new(self.0.f2_beta, self.0.f2_beta_gamma).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hash(&self) -> Digest256 {
|
pub fn hash(&self) -> Digest256 {
|
||||||
|
@ -80,156 +83,82 @@ impl PublicKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tau_g2(&self) -> Spair<G2> {
|
pub fn tau_g2(&self) -> Spair<G2> {
|
||||||
self.f3_tau.clone()
|
self.0.f3_tau.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alpha_a_g1(&self) -> Spair<G1> {
|
pub fn alpha_a_g1(&self) -> Spair<G1> {
|
||||||
self.f4_alpha_a.clone()
|
self.0.f4_alpha_a.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alpha_c_g1(&self) -> Spair<G1> {
|
pub fn alpha_c_g1(&self) -> Spair<G1> {
|
||||||
self.f5_alpha_c.clone()
|
self.0.f5_alpha_c.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rho_b_g1(&self) -> Spair<G1> {
|
pub fn rho_b_g1(&self) -> Spair<G1> {
|
||||||
self.f6_rho_b.clone()
|
self.0.f6_rho_b.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rho_a_rho_b_g1(&self) -> Spair<G1> {
|
pub fn rho_a_rho_b_g1(&self) -> Spair<G1> {
|
||||||
self.f7_rho_a_rho_b.clone()
|
self.0.f7_rho_a_rho_b.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gamma_g1(&self) -> Spair<G1> {
|
pub fn gamma_g1(&self) -> Spair<G1> {
|
||||||
self.f8_gamma.clone()
|
self.0.f8_gamma.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alpha_b_g2(&self) -> Spair<G2> {
|
pub fn alpha_b_g2(&self) -> Spair<G2> {
|
||||||
Spair::new(self.f1_rho_a_rho_b, self.f1_rho_a_rho_b_alpha_b).unwrap()
|
Spair::new(self.0.f1_rho_a_rho_b, self.0.f1_rho_a_rho_b_alpha_b).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rho_a_g2(&self) -> Spair<G2> {
|
pub fn rho_a_g2(&self) -> Spair<G2> {
|
||||||
Spair::new(self.f1, self.f1_rho_a).unwrap()
|
Spair::new(self.0.f1, self.0.f1_rho_a).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rho_b_g2(&self) -> Spair<G2> {
|
pub fn rho_b_g2(&self) -> Spair<G2> {
|
||||||
Spair::new(self.f1_rho_a, self.f1_rho_a_rho_b).unwrap()
|
Spair::new(self.0.f1_rho_a, self.0.f1_rho_a_rho_b).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alpha_a_rho_a_g2(&self) -> Spair<G2> {
|
pub fn alpha_a_rho_a_g2(&self) -> Spair<G2> {
|
||||||
Spair::new(self.f1, self.f1_rho_a_alpha_a).unwrap()
|
Spair::new(self.0.f1, self.0.f1_rho_a_alpha_a).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alpha_b_rho_b_g2(&self) -> Spair<G2> {
|
pub fn alpha_b_rho_b_g2(&self) -> Spair<G2> {
|
||||||
Spair::new(self.f1_rho_a, self.f1_rho_a_rho_b_alpha_b).unwrap()
|
Spair::new(self.0.f1_rho_a, self.0.f1_rho_a_rho_b_alpha_b).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rho_a_rho_b_g2(&self) -> Spair<G2> {
|
pub fn rho_a_rho_b_g2(&self) -> Spair<G2> {
|
||||||
Spair::new(self.f1, self.f1_rho_a_rho_b).unwrap()
|
Spair::new(self.0.f1, self.0.f1_rho_a_rho_b).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alpha_c_rho_a_rho_b_g2(&self) -> Spair<G2> {
|
pub fn alpha_c_rho_a_rho_b_g2(&self) -> Spair<G2> {
|
||||||
Spair::new(self.f1, self.f1_rho_a_rho_b_alpha_c).unwrap()
|
Spair::new(self.0.f1, self.0.f1_rho_a_rho_b_alpha_c).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn beta_g2(&self) -> Spair<G2> {
|
pub fn beta_g2(&self) -> Spair<G2> {
|
||||||
Spair::new(self.f2, self.f2_beta).unwrap()
|
Spair::new(self.0.f2, self.0.f2_beta).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn beta_gamma_g2(&self) -> Spair<G2> {
|
pub fn beta_gamma_g2(&self) -> Spair<G2> {
|
||||||
Spair::new(self.f2, self.f2_beta_gamma).unwrap()
|
Spair::new(self.0.f2, self.0.f2_beta_gamma).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encodable for PublicKey {
|
impl Encodable for PublicKey {
|
||||||
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
|
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
|
||||||
try!(self.f1.encode(s));
|
self.0.encode(s)
|
||||||
try!(self.f1_rho_a.encode(s));
|
|
||||||
try!(self.f1_rho_a_alpha_a.encode(s));
|
|
||||||
try!(self.f1_rho_a_rho_b.encode(s));
|
|
||||||
try!(self.f1_rho_a_rho_b_alpha_c.encode(s));
|
|
||||||
try!(self.f1_rho_a_rho_b_alpha_b.encode(s));
|
|
||||||
try!(self.f2.encode(s));
|
|
||||||
try!(self.f2_beta.encode(s));
|
|
||||||
try!(self.f2_beta_gamma.encode(s));
|
|
||||||
|
|
||||||
try!(self.f3_tau.encode(s));
|
|
||||||
try!(self.f4_alpha_a.encode(s));
|
|
||||||
try!(self.f5_alpha_c.encode(s));
|
|
||||||
try!(self.f6_rho_b.encode(s));
|
|
||||||
try!(self.f7_rho_a_rho_b.encode(s));
|
|
||||||
try!(self.f8_gamma.encode(s));
|
|
||||||
|
|
||||||
try!(self.nizk_tau.encode(s));
|
|
||||||
try!(self.nizk_alpha_a.encode(s));
|
|
||||||
try!(self.nizk_alpha_b.encode(s));
|
|
||||||
try!(self.nizk_alpha_c.encode(s));
|
|
||||||
try!(self.nizk_rho_a.encode(s));
|
|
||||||
try!(self.nizk_rho_b.encode(s));
|
|
||||||
try!(self.nizk_beta.encode(s));
|
|
||||||
try!(self.nizk_gamma.encode(s));
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for PublicKey {
|
impl Decodable for PublicKey {
|
||||||
fn decode<S: Decoder>(s: &mut S) -> Result<PublicKey, S::Error> {
|
fn decode<S: Decoder>(s: &mut S) -> Result<PublicKey, S::Error> {
|
||||||
let f1 = try!(G2::decode(s));
|
let perhaps_valid = PublicKey(
|
||||||
let f1_rho_a = try!(G2::decode(s));
|
try!(PublicKeyInner::decode(s))
|
||||||
let f1_rho_a_alpha_a = try!(G2::decode(s));
|
);
|
||||||
let f1_rho_a_rho_b = try!(G2::decode(s));
|
|
||||||
let f1_rho_a_rho_b_alpha_c = try!(G2::decode(s));
|
|
||||||
let f1_rho_a_rho_b_alpha_b = try!(G2::decode(s));
|
|
||||||
let f2 = try!(G2::decode(s));
|
|
||||||
let f2_beta = try!(G2::decode(s));
|
|
||||||
let f2_beta_gamma = try!(G2::decode(s));
|
|
||||||
|
|
||||||
let f3_tau = try!(Spair::decode(s));
|
|
||||||
let f4_alpha_a = try!(Spair::decode(s));
|
|
||||||
let f5_alpha_c = try!(Spair::decode(s));
|
|
||||||
let f6_rho_b = try!(Spair::decode(s));
|
|
||||||
let f7_rho_a_rho_b = try!(Spair::decode(s));
|
|
||||||
let f8_gamma = try!(Spair::decode(s));
|
|
||||||
|
|
||||||
let nizk_tau = try!(Nizk::decode(s));
|
|
||||||
let nizk_alpha_a = try!(Nizk::decode(s));
|
|
||||||
let nizk_alpha_b = try!(Nizk::decode(s));
|
|
||||||
let nizk_alpha_c = try!(Nizk::decode(s));
|
|
||||||
let nizk_rho_a = try!(Nizk::decode(s));
|
|
||||||
let nizk_rho_b = try!(Nizk::decode(s));
|
|
||||||
let nizk_beta = try!(Nizk::decode(s));
|
|
||||||
let nizk_gamma = try!(Nizk::decode(s));
|
|
||||||
|
|
||||||
let perhaps_valid = PublicKey {
|
|
||||||
f1: f1,
|
|
||||||
f1_rho_a: f1_rho_a,
|
|
||||||
f1_rho_a_alpha_a: f1_rho_a_alpha_a,
|
|
||||||
f1_rho_a_rho_b: f1_rho_a_rho_b,
|
|
||||||
f1_rho_a_rho_b_alpha_c: f1_rho_a_rho_b_alpha_c,
|
|
||||||
f1_rho_a_rho_b_alpha_b: f1_rho_a_rho_b_alpha_b,
|
|
||||||
f2: f2,
|
|
||||||
f2_beta: f2_beta,
|
|
||||||
f2_beta_gamma: f2_beta_gamma,
|
|
||||||
f3_tau: f3_tau,
|
|
||||||
f4_alpha_a: f4_alpha_a,
|
|
||||||
f5_alpha_c: f5_alpha_c,
|
|
||||||
f6_rho_b: f6_rho_b,
|
|
||||||
f7_rho_a_rho_b: f7_rho_a_rho_b,
|
|
||||||
f8_gamma: f8_gamma,
|
|
||||||
nizk_tau: nizk_tau,
|
|
||||||
nizk_alpha_a: nizk_alpha_a,
|
|
||||||
nizk_alpha_b: nizk_alpha_b,
|
|
||||||
nizk_alpha_c: nizk_alpha_c,
|
|
||||||
nizk_rho_a: nizk_rho_a,
|
|
||||||
nizk_rho_b: nizk_rho_b,
|
|
||||||
nizk_beta: nizk_beta,
|
|
||||||
nizk_gamma: nizk_gamma
|
|
||||||
};
|
|
||||||
|
|
||||||
if perhaps_valid.is_valid() {
|
if perhaps_valid.is_valid() {
|
||||||
Ok(perhaps_valid)
|
Ok(perhaps_valid)
|
||||||
} else {
|
} else {
|
||||||
Err(s.error("invalid s-pairs"))
|
Err(s.error("invalid public key"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -334,7 +263,7 @@ impl PrivateKey {
|
||||||
let nizk_beta = Nizk::new(rng, f2, self.beta);
|
let nizk_beta = Nizk::new(rng, f2, self.beta);
|
||||||
let nizk_gamma = f8_gamma.nizk(rng, self.gamma);
|
let nizk_gamma = f8_gamma.nizk(rng, self.gamma);
|
||||||
|
|
||||||
let tmp = PublicKey {
|
let tmp = PublicKey(PublicKeyInner {
|
||||||
f1: f1,
|
f1: f1,
|
||||||
f1_rho_a: f1_rho_a,
|
f1_rho_a: f1_rho_a,
|
||||||
f1_rho_a_alpha_a: f1_rho_a_alpha_a,
|
f1_rho_a_alpha_a: f1_rho_a_alpha_a,
|
||||||
|
@ -360,7 +289,7 @@ impl PrivateKey {
|
||||||
nizk_rho_b: nizk_rho_b,
|
nizk_rho_b: nizk_rho_b,
|
||||||
nizk_beta: nizk_beta,
|
nizk_beta: nizk_beta,
|
||||||
nizk_gamma: nizk_gamma
|
nizk_gamma: nizk_gamma
|
||||||
};
|
});
|
||||||
|
|
||||||
assert!(tmp.is_valid());
|
assert!(tmp.is_valid());
|
||||||
|
|
||||||
|
@ -415,20 +344,20 @@ fn pubkey_consistency() {
|
||||||
|
|
||||||
assert!(pubkey.is_valid());
|
assert!(pubkey.is_valid());
|
||||||
|
|
||||||
breaks_wf(&pubkey, |p| &mut p.f1, true);
|
breaks_wf(&pubkey, |p| &mut p.0.f1, true);
|
||||||
breaks_wf(&pubkey, |p| &mut p.f1_rho_a, true);
|
breaks_wf(&pubkey, |p| &mut p.0.f1_rho_a, true);
|
||||||
breaks_wf(&pubkey, |p| &mut p.f1_rho_a_alpha_a, true);
|
breaks_wf(&pubkey, |p| &mut p.0.f1_rho_a_alpha_a, true);
|
||||||
breaks_wf(&pubkey, |p| &mut p.f1_rho_a_rho_b, true);
|
breaks_wf(&pubkey, |p| &mut p.0.f1_rho_a_rho_b, true);
|
||||||
breaks_wf(&pubkey, |p| &mut p.f1_rho_a_rho_b_alpha_c, true);
|
breaks_wf(&pubkey, |p| &mut p.0.f1_rho_a_rho_b_alpha_c, true);
|
||||||
breaks_wf(&pubkey, |p| &mut p.f2_beta, true);
|
breaks_wf(&pubkey, |p| &mut p.0.f2_beta, true);
|
||||||
breaks_wf(&pubkey, |p| &mut p.f2_beta_gamma, true);
|
breaks_wf(&pubkey, |p| &mut p.0.f2_beta_gamma, true);
|
||||||
|
|
||||||
// We only ever need beta (alone) in G2, so changing the
|
// We only ever need beta (alone) in G2, so changing the
|
||||||
// relationship between f2 and f2_beta cannot be
|
// relationship between f2 and f2_beta cannot be
|
||||||
// inconsistent
|
// inconsistent
|
||||||
breaks_wf(&pubkey, |p| &mut p.f2, false);
|
breaks_wf(&pubkey, |p| &mut p.0.f2, false);
|
||||||
|
|
||||||
// We only ever need alpha_b (alone) in G2 as well, so
|
// We only ever need alpha_b (alone) in G2 as well, so
|
||||||
// f1_rho_a_rho_b_alpha_b cannot be inconsistent with other relationships
|
// f1_rho_a_rho_b_alpha_b cannot be inconsistent with other relationships
|
||||||
breaks_wf(&pubkey, |p| &mut p.f1_rho_a_rho_b_alpha_b, false);
|
breaks_wf(&pubkey, |p| &mut p.0.f1_rho_a_rho_b_alpha_b, false);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue