diff --git a/pedersen/src/ec_point_add_protocol.rs b/pedersen/src/ec_point_add_protocol.rs index 6efe686..b8ae129 100644 --- a/pedersen/src/ec_point_add_protocol.rs +++ b/pedersen/src/ec_point_add_protocol.rs @@ -13,6 +13,7 @@ use rand::{CryptoRng, RngCore}; use crate::{ mul_protocol::MulProof, opening_protocol::OpeningProof, pedersen_config::PedersenComm, pedersen_config::PedersenConfig, transcript::ECPointAdditionTranscript, + transcript::EC_POINT_CHALLENGE_SIZE, }; pub struct ECPointAddProof { @@ -45,7 +46,12 @@ pub struct ECPointAddProof { pub op: OpeningProof

, } -impl ECPointAddProof

{ +impl ECPointAddProof

{ + /// This is just to circumvent an annoying issue with Rust's current generics system. + const MPSIZE: usize = MulProof::

::CHAL_SIZE; + const OPSIZE: usize = OpeningProof::

::CHAL_SIZE; + pub const CHAL_SIZE: usize = 3*Self::MPSIZE + Self::OPSIZE; + fn make_transcript( transcript: &mut Transcript, c1: &PedersenComm

, @@ -115,32 +121,58 @@ impl ECPointAddProof

{ let taua =

::from_ob_to_sf(tau); let c7 = PedersenComm::new(taua, rng); - // Now commit to all of them. + // Now we begin the stage of incorporating everything into the + // transcript. We do this by creating the intermediates for each + // proof (which adds to the transcript in turn), before generating a long + // challenge (with enough space for each sub-proof). We then, finally, + // split up this challenge into smaller slices that can be used by each + // individual proof. Self::make_transcript(transcript, &c1, &c2, &c3, &c4, &c5, &c6, &c7); - // And now we simply invoke each of the sub-protocols. - // TODO: shouldn't all of these proofs be done in parallel? Meaning using one long challenge.. - let z1 = &c3 - &c1; - let z2 = &c4 - &c2; - let x1 =

::from_ob_to_sf(b_x - a_x); - let mp1 = MulProof::create(transcript, rng, &x1, &taua, &z1, &c7, &z2); - - let z4 = &c1 + &c3 + &c5; - let mp2 = MulProof::create(transcript, rng, &taua, &taua, &c7, &c7, &z4); - assert!(mp2.alpha.is_on_curve()); - assert!(mp2.beta.is_on_curve()); - assert!(mp2.delta.is_on_curve()); + // These are the temporaries for the first multiplication proof, which + // verifies that (b_x - a_x)*tau = b_y - a_y. + let z1 = &c3 - &c1; // This is the commitment for b_x - a_x. + let z2 = &c4 - &c2; // This is the commitment for b_y - a_y. - let x3 =

::from_ob_to_sf(a_x - t_x); - - let z5 = &c1 - &c5; - let z6 = &c2 + &c6; - let mp3 = MulProof::create(transcript, rng, &taua, &x3, &c7, &z5, &z6); + let x1 =

::from_ob_to_sf(b_x - a_x); + let mpi1 = MulProof::create_intermediates(transcript, rng, &z1, &c7, &z2); + // These are the temporaries for the second multiplication proof, which verifies that + // tau^2 = a_x + b_x + t_x. + let z4 = &c1 + &c3 + &c5; // This is the commitment to a_x + b_x + t_x. + let mpi2 = MulProof::create_intermediates(transcript, rng, &c7, &c7, &z4); + // These are the temporaries for the third multiplication proof, which verifies that + // tau*(a_x - t_x) = a_y + t_y. + let x3 =

::from_ob_to_sf(a_x - t_x); // Value of a_x - t_x + let z5 = &c1 - &c5; // The commitment to a_x - t_x + let z6 = &c2 + &c6; // The commitment to a_y + t_y. + let mpi3 = MulProof::create_intermediates(transcript, rng, &c7, &z5, &z6); + + // And, finally, the intermediates for the Opening proof. + // This proves that C2 opens to a_y. let ay_sf =

::from_ob_to_sf(a_y); - let op = OpeningProof::create(transcript, rng, &ay_sf, &c2); - + let opi = OpeningProof::create_intermediates(transcript, rng, &c2); + + // Now we make a very large challenge and create the various proofs from the + // intermediates. + let chal_buf = ECPointAdditionTranscript::challenge_scalar(transcript, b"c"); + + // Make sure it all lines up. + assert!(Self::CHAL_SIZE == EC_POINT_CHALLENGE_SIZE); + + // Make the sub-challenges. + let mp1chal = &chal_buf[0..Self::MPSIZE]; + let mp2chal = &chal_buf[Self::MPSIZE..2*Self::MPSIZE]; + let mp3chal = &chal_buf[2*Self::MPSIZE..3*Self::MPSIZE]; + let opchal = &chal_buf[3*Self::MPSIZE..]; + + // And now we build the sub-proofs before returning. + let mp1 = MulProof::create_proof(&x1, &taua, &mpi1, &z1, &c7, &z2, mp1chal); + let mp2 = MulProof::create_proof(&taua, &taua, &mpi2, &c7, &c7, &z4, mp2chal); + let mp3 = MulProof::create_proof(&taua, &x3, &mpi3, &c7, &z5, &z6, mp3chal); + let op = OpeningProof::create_proof(&ay_sf, &opi, &c2, opchal); + // And now we just return. Self { c1: c1, @@ -150,10 +182,10 @@ impl ECPointAddProof

{ c5: c5, c6: c6, c7: c7, - mp1: mp1, - mp2: mp2, - mp3: mp3, - op: op, + mp1: mp1, + mp2: mp2, + mp3: mp3, + op: op, } } @@ -161,7 +193,7 @@ impl ECPointAddProof

{ Self::make_transcript( transcript, &self.c1, &self.c2, &self.c3, &self.c4, &self.c5, &self.c6, &self.c7, ); - + let z1 = &self.c3 - &self.c1; let z2 = &self.c7; let z3 = &self.c4 - &self.c2; @@ -169,9 +201,22 @@ impl ECPointAddProof

{ let z5 = &self.c1 - &self.c5; let z6 = &self.c2 + &self.c6; - self.mp1.verify(transcript, &z1, &z2, &z3) - && self.mp2.verify(transcript, &self.c7, &self.c7, &z4) - && self.mp3.verify(transcript, &z2, &z5, &z6) - && self.op.verify(transcript, &self.c2) + // Rebuild the rest of the transcript. + self.mp1.add_to_transcript(transcript, &z1, &z2, &z3); + self.mp2.add_to_transcript(transcript, &self.c7, &self.c7, &z4); + self.mp3.add_to_transcript(transcript, &z2, &z5, &z6); + self.op.add_to_transcript(transcript, &self.c2); + + // Make the challenges and sub-challenges. + let chal_buf = ECPointAdditionTranscript::challenge_scalar(transcript, b"c"); + let mp1chal = &chal_buf[0..Self::MPSIZE]; + let mp2chal = &chal_buf[Self::MPSIZE..2*Self::MPSIZE]; + let mp3chal = &chal_buf[2*Self::MPSIZE..3*Self::MPSIZE]; + let opchal = &chal_buf[3*Self::MPSIZE..]; + + self.mp1.verify_with_challenge(&z1, &z2, &z3, mp1chal) + && self.mp2.verify_with_challenge(&self.c7, &self.c7, &z4, mp2chal) + && self.mp3.verify_with_challenge(&z2, &z5, &z6, mp3chal) + && self.op.verify_with_challenge(&self.c2, opchal) } } diff --git a/pedersen/src/equality_protocol.rs b/pedersen/src/equality_protocol.rs index 615df36..d99e627 100644 --- a/pedersen/src/equality_protocol.rs +++ b/pedersen/src/equality_protocol.rs @@ -7,20 +7,30 @@ use ark_ec::{ short_weierstrass::{self as sw}, }; -use ark_serialize::{CanonicalSerialize, CanonicalDeserialize}; - +use ark_serialize::CanonicalSerialize; use ark_std::{UniformRand, ops::Mul}; use rand::{RngCore, CryptoRng}; -use crate::{transcript::EqualityTranscript, pedersen_config::PedersenConfig, pedersen_config::PedersenComm}; +use crate::{transcript::EqualityTranscript, pedersen_config::PedersenConfig, pedersen_config::PedersenComm, transcript::CHALLENGE_SIZE}; pub struct EqualityProof { pub alpha: sw::Affine

, pub z :

::ScalarField, } +pub struct EqualityProofIntermediate { + pub r:

::ScalarField, + pub alpha : sw::Affine

, +} + impl EqualityProof

{ + /// This is just to circumvent an annoying issue with Rust's current generics system. + pub const CHAL_SIZE: usize = CHALLENGE_SIZE; + pub fn add_to_transcript(&self, transcript: &mut Transcript, c1: &PedersenComm

, c2: &PedersenComm

) { + Self::make_transcript(transcript, c1, c2, &self.alpha) + } + fn make_transcript(transcript: &mut Transcript, c1: &PedersenComm

, c2: &PedersenComm

, @@ -40,38 +50,46 @@ impl EqualityProof

{ transcript.append_point(b"alpha", &compressed_bytes[..]); } - fn make_challenge(transcript: &mut Transcript) ->

::ScalarField { -

::ScalarField::deserialize_compressed(&transcript.challenge_scalar(b"c")[..]).unwrap() - } - - - pub fn create(transcript: &mut Transcript, + pub fn create_intermediates(transcript: &mut Transcript, rng: &mut T, c1: &PedersenComm

, - c2: &PedersenComm

) -> EqualityProof

{ - + c2: &PedersenComm

) -> EqualityProofIntermediate

{ + let r =

::ScalarField::rand(rng); let alpha = P::GENERATOR2.mul(r).into_affine(); Self::make_transcript(transcript, c1, c2, &alpha); + EqualityProofIntermediate { + r: r, + alpha: alpha + } + } + + pub fn create(transcript: &mut Transcript, + rng: &mut T, + c1: &PedersenComm

, + c2: &PedersenComm

) -> Self { + Self::create_proof(&Self::create_intermediates(transcript, rng, c1, c2), c1, c2, &transcript.challenge_scalar(b"c")[..]) + } - // Now make the challenge. - let chal = Self::make_challenge(transcript); + pub fn create_proof(inter: &EqualityProofIntermediate

, c1: &PedersenComm

, c2: &PedersenComm

, chal_buf: &[u8]) -> Self { - let z = chal * (c1.r - c2.r) + r; + let chal =

::make_challenge_from_buffer(chal_buf); + let z = chal * (c1.r - c2.r) + inter.r; EqualityProof { - alpha: alpha, + alpha: inter.alpha, z: z } } pub fn verify(&self, transcript: &mut Transcript, c1: &PedersenComm

, c2: &PedersenComm

) -> bool { // Make the transcript. - Self::make_transcript(transcript, c1, c2, &self.alpha); - - // Now make the challenge and check. - let chal = Self::make_challenge(transcript); + self.add_to_transcript(transcript, c1, c2); + self.verify_with_challenge(c1, c2, &transcript.challenge_scalar(b"c")[..]) + } - P::GENERATOR2.mul(self.z) == (c1.comm - c2.comm).mul(chal) + self.alpha + pub fn verify_with_challenge(&self, c1: &PedersenComm

, c2: &PedersenComm

, chal_buf: &[u8]) -> bool { + let chal =

::make_challenge_from_buffer(chal_buf); + P::GENERATOR2.mul(self.z) == (c1.comm - c2.comm).mul(chal) + self.alpha } } diff --git a/pedersen/src/mul_protocol.rs b/pedersen/src/mul_protocol.rs index 49c741f..939e439 100644 --- a/pedersen/src/mul_protocol.rs +++ b/pedersen/src/mul_protocol.rs @@ -9,11 +9,11 @@ use ark_ec::{ short_weierstrass::{self as sw}, }; -use ark_serialize::{CanonicalSerialize, CanonicalDeserialize}; +use ark_serialize::CanonicalSerialize; use ark_std::{UniformRand, ops::Mul}; use rand::{RngCore, CryptoRng}; -use crate::{transcript::MulTranscript, pedersen_config::PedersenConfig, pedersen_config::PedersenComm}; +use crate::{transcript::MulTranscript, pedersen_config::PedersenConfig, pedersen_config::PedersenComm, transcript::CHALLENGE_SIZE}; pub struct MulProof { pub alpha: sw::Affine

, @@ -27,8 +27,28 @@ pub struct MulProof { pub z5:

::ScalarField, } +pub struct MulProofIntermediate { + pub alpha: sw::Affine

, + pub beta: sw::Affine

, + pub delta: sw::Affine

, + + pub b1:

::ScalarField, + pub b2:

::ScalarField, + pub b3:

::ScalarField, + pub b4:

::ScalarField, + pub b5:

::ScalarField, +} + impl MulProof

{ + /// This is just to circumvent an annoying issue with Rust's current generics system. + pub const CHAL_SIZE: usize = CHALLENGE_SIZE; + pub fn add_to_transcript(&self, transcript: &mut Transcript, c1: &PedersenComm

, + c2: &PedersenComm

, + c3: &PedersenComm

) { + Self::make_transcript(transcript, c1, c2, c3, &self.alpha, &self.beta, &self.delta) + } + fn make_transcript(transcript: &mut Transcript, c1: &PedersenComm

, c2: &PedersenComm

, @@ -60,11 +80,6 @@ impl MulProof

{ delta.serialize_compressed(&mut compressed_bytes).unwrap(); transcript.append_point(b"delta", &compressed_bytes[..]); } - - - fn make_challenge(transcript: &mut Transcript) ->

::ScalarField { -

::ScalarField::deserialize_compressed(&transcript.challenge_scalar(b"c")[..]).unwrap() - } pub fn create(transcript: &mut Transcript, rng: &mut T, @@ -72,8 +87,15 @@ impl MulProof

{ y: &

::ScalarField, c1: &PedersenComm

, c2: &PedersenComm

, - c3: &PedersenComm

) -> Self { + c3: &PedersenComm

) -> Self { + Self::create_proof(x, y, &Self::create_intermediates(transcript, rng, c1, c2, c3), c1, c2, c3, &transcript.challenge_scalar(b"c")[..]) + } + pub fn create_intermediates(transcript: &mut Transcript, + rng: &mut T, + c1: &PedersenComm

, + c2: &PedersenComm

, + c3: &PedersenComm

) -> MulProofIntermediate

{ // Generate the random values. let b1 =

::ScalarField::rand(rng); let b2 =

::ScalarField::rand(rng); @@ -87,25 +109,39 @@ impl MulProof

{ Self::make_transcript(transcript, c1, c2, c3, &alpha, &beta, &delta); - // Now make the challenge. - let chal = Self::make_challenge(transcript); - + MulProofIntermediate { b1: b1, b2: b2, b3: b3, b4: b4, b5: b5, alpha: alpha, beta: beta, delta: delta } + } + + pub fn create_proof(x: &

::ScalarField, y: &

::ScalarField, + inter: &MulProofIntermediate

, + c1: &PedersenComm

, + c2: &PedersenComm

, + c3: &PedersenComm

, + chal_buf: &[u8]) -> Self { + + // Make the challenge itself. + let chal =

::make_challenge_from_buffer(chal_buf); + Self { - alpha: alpha, - beta: beta, - delta: delta, - z1: b1 + (chal * (x)), - z2: b2 + (chal * c1.r), - z3: b3 + (chal * (y)), - z4: b4 + (chal * c2.r), - z5: b5 + chal * (c3.r - (c1.r*(y))) + alpha: inter.alpha, + beta: inter.beta, + delta: inter.delta, + z1: inter.b1 + (chal * (x)), + z2: inter.b2 + (chal * c1.r), + z3: inter.b3 + (chal * (y)), + z4: inter.b4 + (chal * c2.r), + z5: inter.b5 + chal * (c3.r - (c1.r*(y))) } } pub fn verify(&self, transcript: &mut Transcript, c1: &PedersenComm

, c2: &PedersenComm

, c3: &PedersenComm

) -> bool { Self::make_transcript(transcript, c1, c2, c3, &self.alpha, &self.beta, &self.delta); - let chal = Self::make_challenge(transcript); - + self.verify_with_challenge(c1, c2, c3, &transcript.challenge_scalar(b"c")[..]) + } + + + pub fn verify_with_challenge(&self, c1: &PedersenComm

, c2: &PedersenComm

, c3: &PedersenComm

, chal_buf: &[u8]) -> bool { + let chal =

::make_challenge_from_buffer(chal_buf); (self.alpha + c1.comm.mul(chal) == P::GENERATOR.mul(self.z1) + P::GENERATOR2.mul(self.z2)) && (self.beta + c2.comm.mul(chal) == P::GENERATOR.mul(self.z3) + P::GENERATOR2.mul(self.z4)) && (self.delta + c3.comm.mul(chal) == c1.comm.mul(self.z3) + P::GENERATOR2.mul(self.z5)) diff --git a/pedersen/src/opening_protocol.rs b/pedersen/src/opening_protocol.rs index 280b25b..1e9d92d 100644 --- a/pedersen/src/opening_protocol.rs +++ b/pedersen/src/opening_protocol.rs @@ -14,7 +14,7 @@ use ark_serialize::{CanonicalSerialize, CanonicalDeserialize}; use ark_std::{UniformRand, ops::Mul}; use rand::{RngCore, CryptoRng}; -use crate::{transcript::OpeningTranscript, pedersen_config::PedersenConfig, pedersen_config::PedersenComm}; +use crate::{transcript::OpeningTranscript, pedersen_config::PedersenConfig, pedersen_config::PedersenComm, transcript::CHALLENGE_SIZE}; pub struct OpeningProof { pub alpha: sw::Affine

, @@ -22,8 +22,20 @@ pub struct OpeningProof { pub z2:

::ScalarField, } +pub struct OpenProofIntermediate { + pub alpha: sw::Affine

, + pub t1:

::ScalarField, + pub t2:

::ScalarField, +} + impl OpeningProof

{ + /// This is just to circumvent an annoying issue with Rust's current generics system. + pub const CHAL_SIZE: usize = CHALLENGE_SIZE; + pub fn add_to_transcript(&self, transcript: &mut Transcript, c1: &PedersenComm

) { + Self::make_transcript(transcript, c1, &self.alpha) + } + fn make_transcript(transcript: &mut Transcript, c1: &PedersenComm

, alpha_p: &sw::Affine

) { @@ -40,8 +52,8 @@ impl OpeningProof

{ transcript.append_point(b"alpha", &compressed_bytes[..]); } - fn make_challenge(transcript: &mut Transcript) ->

::ScalarField { -

::ScalarField::deserialize_compressed(&transcript.challenge_scalar(b"c")[..]).unwrap() + fn make_challenge_from_buffer(chal_buf: &[u8]) ->

::ScalarField { +

::ScalarField::deserialize_compressed(chal_buf).unwrap() } pub fn create(transcript: &mut Transcript, @@ -49,28 +61,47 @@ impl OpeningProof

{ x: &

::ScalarField, c1: &PedersenComm

) -> Self { + let inter = Self::create_intermediates(transcript, rng, c1); + + // Now call the routine that returns the "challenged" version. + // N.B For the sake of compatibility, here we just pass the buffer itself. + let chal_buf = transcript.challenge_scalar(b"c"); + Self::create_proof(x, &inter, c1, &chal_buf) + } + + pub fn create_intermediates(transcript: &mut Transcript, + rng: &mut T, + c1: &PedersenComm

) -> OpenProofIntermediate

{ let t1 =

::ScalarField::rand(rng); let t2 =

::ScalarField::rand(rng); let alpha = (P::GENERATOR.mul(t1) + P::GENERATOR2.mul(t2)).into_affine(); Self::make_transcript(transcript, c1, &alpha); - // Now make the challenge. - let chal = Self::make_challenge(transcript); + OpenProofIntermediate { t1: t1, t2: t2, alpha: alpha } + } - OpeningProof { - alpha: alpha, - z1: *x*chal + t1, - z2: c1.r * chal + t2 - } + pub fn create_proof(x: &

::ScalarField, inter: &OpenProofIntermediate

, + c1: &PedersenComm

, chal_buf : &[u8]) -> Self { + // Make the challenge itself. + let chal = Self::make_challenge_from_buffer(chal_buf); + Self { + alpha: inter.alpha, + z1: *x*chal + inter.t1, + z2: c1.r * chal + inter.t2 + } } pub fn verify(&self, transcript: &mut Transcript, c1: &PedersenComm

) -> bool { // Make the transcript. - Self::make_transcript(transcript, c1, &self.alpha); - - // Now make the challenge and check. - let chal = Self::make_challenge(transcript); + self.add_to_transcript(transcript, c1); + + // Now check make the challenge and delegate. + self.verify_with_challenge(c1, &transcript.challenge_scalar(b"c")[..]) + } + pub fn verify_with_challenge(&self, c1: &PedersenComm

, chal_buf: &[u8]) -> bool { + // Make the challenge and check. + let chal = Self::make_challenge_from_buffer(chal_buf); P::GENERATOR.mul(self.z1) + P::GENERATOR2.mul(self.z2) == c1.comm.mul(chal) + self.alpha } } diff --git a/pedersen/src/pedersen_config.rs b/pedersen/src/pedersen_config.rs index 4518ffb..92d70ff 100644 --- a/pedersen/src/pedersen_config.rs +++ b/pedersen/src/pedersen_config.rs @@ -9,6 +9,7 @@ use ark_ec::{ use ark_std::{UniformRand, ops::Mul}; use std::ops; use rand::{RngCore, CryptoRng}; +use ark_serialize::CanonicalDeserialize; pub trait PedersenConfig : SWCurveConfig { /// Second generator that's used in Pedersen commitments. @@ -23,7 +24,14 @@ pub trait PedersenConfig : SWCurveConfig { ::ScalarField::from(x_bt) } - fn from_ob_to_sf(x: ::BaseField) -> ::ScalarField; + fn from_ob_to_sf(x: ::BaseField) -> ::ScalarField; + + + /// This function turns a challenge buffer into a challenge point. This is primarily to circumvent + /// an issue with Merlin (which primarily deals with Ristretto points). + fn make_challenge_from_buffer(chal_buf: &[u8]) -> ::ScalarField { + ::ScalarField::deserialize_compressed(chal_buf).unwrap() + } } #[derive(Copy, Clone)] diff --git a/pedersen/src/transcript.rs b/pedersen/src/transcript.rs index c497401..a966b7a 100644 --- a/pedersen/src/transcript.rs +++ b/pedersen/src/transcript.rs @@ -5,7 +5,10 @@ use merlin::Transcript; -pub trait EqualityTranscript { +// This is needed here to circumvent a rust issue. +pub const CHALLENGE_SIZE : usize = 64; + +pub trait EqualityTranscript { /// Append a domain separator. fn domain_sep(&mut self); @@ -13,10 +16,10 @@ pub trait EqualityTranscript { fn append_point(&mut self, label: &'static[u8], point: &[u8]); /// Produce the challenge. - fn challenge_scalar(&mut self, label: &'static[u8]) -> [u8; 64]; + fn challenge_scalar(&mut self, label: &'static[u8]) -> [u8; CHALLENGE_SIZE]; } -impl EqualityTranscript for Transcript { +impl EqualityTranscript for Transcript { fn domain_sep(&mut self) { self.append_message(b"dom-sep", b"equality-proof") } @@ -25,15 +28,15 @@ impl EqualityTranscript for Transcript { self.append_message(label, point); } - fn challenge_scalar(&mut self, label: &'static[u8]) -> [u8; 64] { - let mut buf = [0u8; 64]; + fn challenge_scalar(&mut self, label: &'static[u8]) -> [u8; CHALLENGE_SIZE] { + let mut buf = [0u8; CHALLENGE_SIZE]; self.challenge_bytes(label, &mut buf); buf } } -pub trait OpeningTranscript { +pub trait OpeningTranscript { /// Append a domain separator. fn domain_sep(&mut self); @@ -41,10 +44,10 @@ pub trait OpeningTranscript { fn append_point(&mut self, label: &'static[u8], point: &[u8]); /// Produce the challenge. - fn challenge_scalar(&mut self, label: &'static[u8]) -> [u8; 64]; + fn challenge_scalar(&mut self, label: &'static[u8]) -> [u8; CHALLENGE_SIZE]; } -impl OpeningTranscript for Transcript { +impl OpeningTranscript for Transcript { fn domain_sep(&mut self) { self.append_message(b"dom-sep", b"open-proof") } @@ -53,14 +56,14 @@ impl OpeningTranscript for Transcript { self.append_message(label, point); } - fn challenge_scalar(&mut self, label: &'static[u8]) -> [u8; 64] { - let mut buf = [0u8; 64]; + fn challenge_scalar(&mut self, label: &'static[u8]) -> [u8; CHALLENGE_SIZE] { + let mut buf = [0u8; CHALLENGE_SIZE]; self.challenge_bytes(label, &mut buf); buf } } -pub trait MulTranscript { +pub trait MulTranscript { /// Append a domain separator. fn domain_sep(&mut self); @@ -68,7 +71,7 @@ pub trait MulTranscript { fn append_point(&mut self, label: &'static[u8], point: &[u8]); /// Produce the challenge. - fn challenge_scalar(&mut self, label: &'static[u8]) -> [u8; 64]; + fn challenge_scalar(&mut self, label: &'static[u8]) -> [u8; CHALLENGE_SIZE]; } impl MulTranscript for Transcript { @@ -80,15 +83,17 @@ impl MulTranscript for Transcript { self.append_message(label, point); } - fn challenge_scalar(&mut self, label: &'static[u8]) -> [u8; 64] { - let mut buf = [0u8; 64]; + fn challenge_scalar(&mut self, label: &'static[u8]) -> [u8; CHALLENGE_SIZE] { + let mut buf = [0u8; CHALLENGE_SIZE]; self.challenge_bytes(label, &mut buf); buf } } -pub trait ECPointAdditionTranscript { +/// The size of the challenge for elliptic curve challenges. +pub const EC_POINT_CHALLENGE_SIZE: usize = 4 * CHALLENGE_SIZE; +pub trait ECPointAdditionTranscript { /// Append a domain separator. fn domain_sep(&mut self); @@ -96,7 +101,7 @@ pub trait ECPointAdditionTranscript { fn append_point(&mut self, label: &'static[u8], point: &[u8]); /// Produce the challenge. - fn challenge_scalar(&mut self, label: &'static[u8]) -> [u8; 64]; + fn challenge_scalar(&mut self, label: &'static[u8]) -> [u8; EC_POINT_CHALLENGE_SIZE]; } impl ECPointAdditionTranscript for Transcript { @@ -109,8 +114,8 @@ impl ECPointAdditionTranscript for Transcript { self.append_message(label, point); } - fn challenge_scalar(&mut self, label: &'static[u8]) -> [u8; 64] { - let mut buf = [0u8; 64]; + fn challenge_scalar(&mut self, label: &'static[u8]) -> [u8; EC_POINT_CHALLENGE_SIZE] { + let mut buf = [0u8; EC_POINT_CHALLENGE_SIZE]; self.challenge_bytes(label, &mut buf); buf }