group: Move uncompressed encodings to an UncompressedEncoding trait

Specifications of deployed elliptic curves fall into one of two
categories:
- They specify both compressed and uncompressed encodings, allowing
  implementations to use either depending on performance vs data size
  considerations.
- They specify a single point encoding format using point compression.

I am unaware of any elliptic curve specification that explicitly forbids
compressed encodings.

To support both categories of elliptic curves, we provide the
CurveAffine::Compressed associated type which all curves must define,
and then curves that additionally specify an uncompressed encoding may
implement the UncompressedEncoding trait and its Uncompressed associated
type.

pairing::PairingCurveAffine continues to require that its groups provide
uncompressed encodings, because this is relied upon by bellman::groth16.
We can revisit this restriction when that module is refactored as a
separate crate.
This commit is contained in:
Jack Grigg 2020-05-21 11:48:52 +12:00
parent a1a27128f2
commit 06c2c37b28
2 changed files with 10 additions and 7 deletions

View File

@ -2,7 +2,7 @@
//!
//! [Groth16]: https://eprint.iacr.org/2016/260
use group::CurveAffine;
use group::{CurveAffine, UncompressedEncoding};
use pairing::{Engine, MultiMillerLoop};
use crate::SynthesisError;
@ -158,7 +158,7 @@ impl<E: Engine> VerifyingKey<E> {
pub fn read<R: Read>(mut reader: R) -> io::Result<Self> {
let read_g1 = |reader: &mut R| -> io::Result<E::G1Affine> {
let mut g1_repr = <E::G1Affine as CurveAffine>::Uncompressed::default();
let mut g1_repr = <E::G1Affine as UncompressedEncoding>::Uncompressed::default();
reader.read_exact(g1_repr.as_mut())?;
let affine = E::G1Affine::from_uncompressed(&g1_repr);
@ -170,7 +170,7 @@ impl<E: Engine> VerifyingKey<E> {
};
let read_g2 = |reader: &mut R| -> io::Result<E::G2Affine> {
let mut g2_repr = <E::G2Affine as CurveAffine>::Uncompressed::default();
let mut g2_repr = <E::G2Affine as UncompressedEncoding>::Uncompressed::default();
reader.read_exact(g2_repr.as_mut())?;
let affine = E::G2Affine::from_uncompressed(&g2_repr);
@ -289,7 +289,7 @@ impl<E: Engine> Parameters<E> {
pub fn read<R: Read>(mut reader: R, checked: bool) -> io::Result<Self> {
let read_g1 = |reader: &mut R| -> io::Result<E::G1Affine> {
let mut repr = <E::G1Affine as CurveAffine>::Uncompressed::default();
let mut repr = <E::G1Affine as UncompressedEncoding>::Uncompressed::default();
reader.read_exact(repr.as_mut())?;
let affine = if checked {
@ -317,7 +317,7 @@ impl<E: Engine> Parameters<E> {
};
let read_g2 = |reader: &mut R| -> io::Result<E::G2Affine> {
let mut repr = <E::G2Affine as CurveAffine>::Uncompressed::default();
let mut repr = <E::G2Affine as UncompressedEncoding>::Uncompressed::default();
reader.read_exact(repr.as_mut())?;
let affine = if checked {

View File

@ -1,5 +1,5 @@
use ff::{Field, PrimeField};
use group::{CurveAffine, CurveProjective, Group, PrimeGroup};
use group::{CurveAffine, CurveProjective, Group, PrimeGroup, UncompressedEncoding};
use pairing::{Engine, MillerLoopResult, MultiMillerLoop, PairingCurveAffine};
use rand_core::RngCore;
@ -434,7 +434,6 @@ impl AsRef<[u8]> for FakePoint {
impl CurveAffine for Fr {
type Compressed = FakePoint;
type Uncompressed = FakePoint;
type Projective = Fr;
type Scalar = Fr;
@ -465,6 +464,10 @@ impl CurveAffine for Fr {
fn to_compressed(&self) -> Self::Compressed {
unimplemented!()
}
}
impl UncompressedEncoding for Fr {
type Uncompressed = FakePoint;
fn from_uncompressed(_bytes: &Self::Uncompressed) -> CtOption<Self> {
unimplemented!()