Skip to content

Commit

Permalink
Improve point serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
Denis committed Jul 26, 2021
1 parent 373672f commit 86a1844
Show file tree
Hide file tree
Showing 19 changed files with 358 additions and 246 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ rand_legacy = { package = "rand", version = "0.6" }
ring-algorithm = "0.2.3"
rust-crypto = "^0.2"
serde = { version = "1.0", features = ["derive"] }
serde_bytes = "0.11"
serde_derive = "1.0"
sha2 = "0.8.0"
sha3 = "0.8.2"
Expand Down
2 changes: 1 addition & 1 deletion src/cryptographic_primitives/hashing/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ where
}

fn input_point<E: Curve>(&mut self, point: &Point<E>) {
self.input(&point.to_bytes(false))
self.input(&point.to_bytes(false)[..])
}

fn input_scalar<E: Curve>(&mut self, scalar: &Scalar<E>) {
Expand Down
2 changes: 1 addition & 1 deletion src/cryptographic_primitives/hashing/hash_sha256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl Hash for HSha256 {
fn create_hash_from_ge<E: Curve>(ge_vec: &[&Point<E>]) -> Scalar<E> {
let mut hasher = Sha256::new();
for value in ge_vec {
hasher.input(&value.to_bytes(false));
hasher.input(&value.to_bytes(false)[..]);
}

let result_hex = hasher.result();
Expand Down
2 changes: 1 addition & 1 deletion src/cryptographic_primitives/hashing/hash_sha512.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl Hash for HSha512 {
fn create_hash_from_ge<E: Curve>(ge_vec: &[&Point<E>]) -> Scalar<E> {
let mut hasher = Sha512::new();
for value in ge_vec {
hasher.input(&value.to_bytes(false));
hasher.input(&value.to_bytes(false)[..]);
}

let result_hex = hasher.result();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,13 @@ impl Party1FirstMessage {
// we use hash based commitment
let pk_commitment_blind_factor = BigInt::sample(SECURITY_BITS);
let pk_commitment = HashCommitment::create_commitment_with_user_defined_randomness(
&BigInt::from_bytes(&public_share.to_bytes(true)),
&BigInt::from_bytes(public_share.to_bytes(true).as_ref()),
&pk_commitment_blind_factor,
);

let zk_pok_blind_factor = BigInt::sample(SECURITY_BITS);
let zk_pok_commitment = HashCommitment::create_commitment_with_user_defined_randomness(
&BigInt::from_bytes(&d_log_proof.pk_t_rand_commitment.to_bytes(true)),
&BigInt::from_bytes(d_log_proof.pk_t_rand_commitment.to_bytes(true).as_ref()),
&zk_pok_blind_factor,
);
let ec_key_pair = EcKeyPair {
Expand Down Expand Up @@ -115,13 +115,13 @@ impl Party1FirstMessage {

let pk_commitment_blind_factor = BigInt::sample(SECURITY_BITS);
let pk_commitment = HashCommitment::create_commitment_with_user_defined_randomness(
&BigInt::from_bytes(&public_share.to_bytes(true)),
&BigInt::from_bytes(public_share.to_bytes(true).as_ref()),
&pk_commitment_blind_factor,
);

let zk_pok_blind_factor = BigInt::sample(SECURITY_BITS);
let zk_pok_commitment = HashCommitment::create_commitment_with_user_defined_randomness(
&BigInt::from_bytes(&d_log_proof.pk_t_rand_commitment.to_bytes(true)),
&BigInt::from_bytes(d_log_proof.pk_t_rand_commitment.to_bytes(true).as_ref()),
&zk_pok_blind_factor,
);

Expand Down Expand Up @@ -214,7 +214,7 @@ impl Party2SecondMessage {
let mut flag = true;
if party_one_pk_commitment
!= &HashCommitment::create_commitment_with_user_defined_randomness(
&BigInt::from_bytes(&party_one_public_share.to_bytes(true)),
&BigInt::from_bytes(party_one_public_share.to_bytes(true).as_ref()),
&party_one_pk_commitment_blind_factor,
)
{
Expand All @@ -223,7 +223,12 @@ impl Party2SecondMessage {

if party_one_zk_pok_commitment
!= &HashCommitment::create_commitment_with_user_defined_randomness(
&BigInt::from_bytes(&party_one_d_log_proof.pk_t_rand_commitment.to_bytes(true)),
&BigInt::from_bytes(
party_one_d_log_proof
.pk_t_rand_commitment
.to_bytes(true)
.as_ref(),
),
&party_one_zk_pok_blind_factor,
)
{
Expand Down
26 changes: 11 additions & 15 deletions src/elliptic/curves/bls12_381/g1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ impl ECPoint for G1Point {
type Scalar = FieldScalar;
type Underlying = PK;

type CompressedPoint = G1Compressed;
type UncompressedPoint = G1Uncompressed;

fn zero() -> G1Point {
G1Point {
purpose: "zero",
Expand Down Expand Up @@ -148,23 +151,16 @@ impl ECPoint for G1Point {
}
}

fn serialize(&self, compressed: bool) -> Vec<u8> {
if self.is_zero() {
vec![0]
} else if compressed {
G1Compressed::from_affine(self.ge).as_ref().to_vec()
} else {
G1Uncompressed::from_affine(self.ge).as_ref().to_vec()
}
fn serialize_compressed(&self) -> Self::CompressedPoint {
G1Compressed::from_affine(self.ge)
}

fn serialize_uncompressed(&self) -> Self::UncompressedPoint {
G1Uncompressed::from_affine(self.ge)
}

fn deserialize(bytes: &[u8]) -> Result<G1Point, DeserializationError> {
if bytes == [0] {
Ok(G1Point {
purpose: "deserialize",
ge: Self::zero().ge,
})
} else if bytes.len() == COMPRESSED_SIZE {
if bytes.len() == COMPRESSED_SIZE {
let mut compressed = G1Compressed::empty();
compressed.as_mut().copy_from_slice(bytes);
Ok(G1Point {
Expand Down Expand Up @@ -264,7 +260,7 @@ impl fmt::Debug for G1Point {
f,
"Point {{ purpose: {:?}, uncompressed: {:?} }}",
self.purpose,
hex::encode(self.serialize(false)),
hex::encode(self.serialize_uncompressed()),
)
}
}
Expand Down
26 changes: 11 additions & 15 deletions src/elliptic/curves/bls12_381/g2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ impl ECPoint for G2Point {
type Scalar = FieldScalar;
type Underlying = PK;

type CompressedPoint = G2Compressed;
type UncompressedPoint = G2Uncompressed;

fn zero() -> G2Point {
G2Point {
purpose: "zero",
Expand Down Expand Up @@ -155,23 +158,16 @@ impl ECPoint for G2Point {
}
}

fn serialize(&self, compressed: bool) -> Vec<u8> {
if self.is_zero() {
vec![0]
} else if compressed {
G2Compressed::from_affine(self.ge).as_ref().to_vec()
} else {
G2Uncompressed::from_affine(self.ge).as_ref().to_vec()
}
fn serialize_compressed(&self) -> Self::CompressedPoint {
G2Compressed::from_affine(self.ge)
}

fn serialize_uncompressed(&self) -> Self::UncompressedPoint {
G2Uncompressed::from_affine(self.ge)
}

fn deserialize(bytes: &[u8]) -> Result<G2Point, DeserializationError> {
if bytes == [0] {
Ok(G2Point {
purpose: "deserialize",
ge: Self::zero().ge,
})
} else if bytes.len() == COMPRESSED_SIZE {
if bytes.len() == COMPRESSED_SIZE {
let mut compressed = G2Compressed::empty();
compressed.as_mut().copy_from_slice(bytes);
Ok(G2Point {
Expand Down Expand Up @@ -271,7 +267,7 @@ impl fmt::Debug for G2Point {
f,
"Point {{ purpose: {:?}, uncompressed: {:?} }}",
self.purpose,
hex::encode(self.serialize(false)),
hex::encode(self.serialize_uncompressed()),
)
}
}
Expand Down
14 changes: 11 additions & 3 deletions src/elliptic/curves/curve_ristretto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ lazy_static::lazy_static! {

static ref BASE_POINT2: RistrettoPoint = {
let g = RistrettoPoint::generator();
let hash = Sha256::digest(&g.serialize(true));
let hash = Sha256::digest(g.serialize_compressed().as_ref());
RistrettoPoint {
purpose: "base_point2",
ge: RistrettoPoint::deserialize(&hash).unwrap().ge,
Expand Down Expand Up @@ -207,6 +207,9 @@ impl ECPoint for RistrettoPoint {
type Scalar = RistrettoScalar;
type Underlying = PK;

type CompressedPoint = [u8; 32];
type UncompressedPoint = [u8; 32];

fn zero() -> RistrettoPoint {
RistrettoPoint {
purpose: "zero",
Expand Down Expand Up @@ -248,9 +251,14 @@ impl ECPoint for RistrettoPoint {
None
}

fn serialize(&self, _compressed: bool) -> Vec<u8> {
self.ge.compress().to_bytes().to_vec()
fn serialize_compressed(&self) -> Self::CompressedPoint {
self.ge.compress().to_bytes()
}

fn serialize_uncompressed(&self) -> Self::UncompressedPoint {
self.ge.compress().to_bytes()
}

fn deserialize(bytes: &[u8]) -> Result<RistrettoPoint, DeserializationError> {
let mut buffer = [0u8; 32];
let n = bytes.len();
Expand Down
15 changes: 11 additions & 4 deletions src/elliptic/curves/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ lazy_static::lazy_static! {
};

static ref BASE_POINT2: Ed25519Point = {
let bytes = GENERATOR.serialize(true);
let hashed = sha2::Sha256::digest(&bytes);
let bytes = GENERATOR.serialize_compressed();
let hashed = sha2::Sha256::digest(bytes.as_ref());
let hashed_twice = sha2::Sha256::digest(&hashed);
let p = Ed25519Point::deserialize(&hashed_twice).unwrap();
let eight = Ed25519Scalar::from_bigint(&BigInt::from(8));
Expand Down Expand Up @@ -307,6 +307,9 @@ impl ECPoint for Ed25519Point {
type Underlying = PK;
type Scalar = Ed25519Scalar;

type CompressedPoint = [u8; 32];
type UncompressedPoint = [u8; 32];

fn zero() -> Ed25519Point {
*ZERO
}
Expand Down Expand Up @@ -360,8 +363,12 @@ impl ECPoint for Ed25519Point {
Some(PointCoords { x: xrecover(&y), y })
}

fn serialize(&self, _compress: bool) -> Vec<u8> {
self.ge.to_bytes().to_vec()
fn serialize_compressed(&self) -> Self::CompressedPoint {
self.ge.to_bytes()
}

fn serialize_uncompressed(&self) -> Self::UncompressedPoint {
self.ge.to_bytes()
}

fn deserialize(bytes: &[u8]) -> Result<Ed25519Point, DeserializationError> {
Expand Down
2 changes: 1 addition & 1 deletion src/elliptic/curves/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ pub use self::{
};
pub use self::{
traits::{Curve, ECPoint, ECScalar, PointCoords},
wrappers::{Generator, Point, PointRef, Scalar},
wrappers::{EncodedPoint, Generator, Point, PointRef, Scalar},
};

pub mod error {
Expand Down
13 changes: 10 additions & 3 deletions src/elliptic/curves/p256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@ impl ECPoint for Secp256r1Point {
type Scalar = Secp256r1Scalar;
type Underlying = PK;

type CompressedPoint = EncodedPoint;
type UncompressedPoint = EncodedPoint;

fn zero() -> Secp256r1Point {
Secp256r1Point {
purpose: "zero",
Expand Down Expand Up @@ -271,8 +274,12 @@ impl ECPoint for Secp256r1Point {
Some(PointCoords { x, y })
}

fn serialize(&self, compressed: bool) -> Vec<u8> {
self.ge.to_encoded_point(compressed).to_bytes().into()
fn serialize_compressed(&self) -> Self::CompressedPoint {
self.ge.to_encoded_point(true)
}

fn serialize_uncompressed(&self) -> Self::UncompressedPoint {
self.ge.to_encoded_point(false)
}

fn deserialize(bytes: &[u8]) -> Result<Self, DeserializationError> {
Expand Down Expand Up @@ -362,7 +369,7 @@ mod tests {
let base_point2 = GE::base_point2();

let g = GE::generator();
let hash = Sha256::digest(&g.serialize(true));
let hash = Sha256::digest(g.serialize_compressed().as_ref());
let hash = Sha256::digest(&hash);

assert_eq!(BigInt::from_bytes(&hash), base_point2.x_coord().unwrap());
Expand Down
21 changes: 15 additions & 6 deletions src/elliptic/curves/secp256_k1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,9 @@ impl ECPoint for Secp256k1Point {
type Scalar = Secp256k1Scalar;
type Underlying = Option<PK>;

type CompressedPoint = [u8; 33];
type UncompressedPoint = [u8; 65];

fn zero() -> Secp256k1Point {
Secp256k1Point {
purpose: "zero",
Expand Down Expand Up @@ -392,16 +395,22 @@ impl ECPoint for Secp256k1Point {
}
}

fn serialize(&self, compressed: bool) -> Vec<u8> {
fn serialize_compressed(&self) -> Self::CompressedPoint {
match self.ge {
None => [0u8; 33],
Some(ge) => ge.serialize(),
}
}

fn serialize_uncompressed(&self) -> Self::UncompressedPoint {
match self.ge {
None => vec![0],
Some(ge) if compressed => ge.serialize().to_vec(),
Some(ge) => ge.serialize_uncompressed().to_vec(),
None => [0u8; 65],
Some(ge) => ge.serialize_uncompressed(),
}
}

fn deserialize(bytes: &[u8]) -> Result<Secp256k1Point, DeserializationError> {
if bytes == [0] {
if bytes == [0; 33] || bytes == [0; 65] {
Ok(Secp256k1Point {
purpose: "from_bytes",
ge: None,
Expand Down Expand Up @@ -520,7 +529,7 @@ mod test {
let base_point2 = GE::base_point2();

let g = GE::generator();
let hash = Sha256::digest(&g.serialize(true));
let hash = Sha256::digest(&g.serialize_compressed());
let hash = Sha256::digest(&hash);
let hash = Sha256::digest(&hash);

Expand Down
19 changes: 10 additions & 9 deletions src/elliptic/curves/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,23 +83,24 @@ fn serialize_deserialize_point<E: Curve>() {
let rand_point = <E::Point as ECPoint>::generator().scalar_mul(&random_nonzero_scalar());
let zero = E::Point::zero();
for point in [rand_point, zero] {
for compressed in [true, false] {
let bytes = point.serialize(compressed);
let deserialized = <E::Point as ECPoint>::deserialize(&bytes).unwrap();
assert_eq!(point, deserialized);
}
let bytes = point.serialize_compressed();
let deserialized = <E::Point as ECPoint>::deserialize(bytes.as_ref()).unwrap();
assert_eq!(point, deserialized);
let bytes = point.serialize_uncompressed();
let deserialized = <E::Point as ECPoint>::deserialize(bytes.as_ref()).unwrap();
assert_eq!(point, deserialized);
}
}

test_for_all_curves!(zero_point_serialization);
fn zero_point_serialization<E: Curve>() {
let point: E::Point = ECPoint::zero();
let bytes = point.serialize(true);
let point_from_compressed: E::Point = ECPoint::deserialize(&bytes).unwrap();
let bytes = point.serialize_compressed();
let point_from_compressed: E::Point = ECPoint::deserialize(bytes.as_ref()).unwrap();
assert_eq!(point, point_from_compressed);

let bytes = point.serialize(false);
let point_from_uncompressed: E::Point = ECPoint::deserialize(&bytes).unwrap();
let bytes = point.serialize_uncompressed();
let point_from_uncompressed: E::Point = ECPoint::deserialize(bytes.as_ref()).unwrap();
assert_eq!(point, point_from_uncompressed);
}

Expand Down
Loading

0 comments on commit 86a1844

Please sign in to comment.