fn assemble_shares(&mut self, proof_shares: &[ProofShare]) -> Result<RangeProof, MpcError> {
        if self.m != proof_shares.len() {
            return Err(MpcError::WrongNumProofShares);
        }

        // Validate lengths for each share
        let mut bad_shares = Vec::<usize>::new(); // no allocations until we append
        for (j, share) in proof_shares.iter().enumerate() {
            share
                .check_size(self.n, &self.bp_gens, j)
                .unwrap_or_else(|_| {
                    bad_shares.push(j);
                });
        }

        if !bad_shares.is_empty() {
            return Err(MpcError::MalformedProofShares { bad_shares });
        }

        let t_x: Scalar = proof_shares.iter().map(|ps| ps.t_x).sum();
        let t_x_blinding: Scalar = proof_shares.iter().map(|ps| ps.t_x_blinding).sum();
        let e_blinding: Scalar = proof_shares.iter().map(|ps| ps.e_blinding).sum();

        // Get a challenge value to combine statements for the IPP
        let mut input = self.poly_challenge.x.as_bytes().to_vec();
        input.extend_from_slice(self.poly_challenge.x.as_bytes());
        input.extend_from_slice(t_x_blinding.as_bytes());
        input.extend_from_slice(e_blinding.as_bytes());
        input.extend_from_slice(t_x.as_bytes());

        let mut w = [0u8; 32];
        keccak_256(&input, &mut w);
        // TODO: Monero checks if w is equal to zero and aborts if so (bulletproof.cc:720)
        let w = Scalar::from_bytes_mod_order(w);
        let Q = w * self.pc_gens.B;

        let G_factors: Vec<Scalar> = iter::repeat(Scalar::one()).take(self.n * self.m).collect();
        let H_factors: Vec<Scalar> = util::exp_iter(self.bit_challenge.y.invert())
            .take(self.n * self.m)
            .collect();

        let l_vec: Vec<Scalar> = proof_shares
            .iter()
            .flat_map(|ps| ps.l_vec.clone().into_iter())
            .collect();
        let r_vec: Vec<Scalar> = proof_shares
            .iter()
            .flat_map(|ps| ps.r_vec.clone().into_iter())
            .collect();

        let ipp_proof = inner_product_proof::InnerProductProof::create(
            &w,
            &Q,
            &G_factors,
            &H_factors,
            self.bp_gens.G(self.n, self.m).cloned().collect(),
            self.bp_gens.H(self.n, self.m).cloned().collect(),
            l_vec,
            r_vec,
        );

        Ok(RangeProof {
            A: self.A,
            S: self.S,
            T_1: self.T_1,
            T_2: self.T_2,
            t_x,
            t_x_blinding,
            e_blinding,
            ipp_proof,
        })
    }
/// Assembles proof shares into an `RangeProof`.
Assembles proof shares into an `RangeProof`.
Assembles proof shares into an ` RangeProof ` .
fn assemble_shares(&mut self, proof_shares: &[ProofShare]) -> Result<RangeProof, MpcError> {
        if self.m != proof_shares.len() {
            return Err(MpcError::WrongNumProofShares);
        }
        // Validate lengths for each share
        let mut bad_shares = Vec::<usize>::new(); // no allocations until we append
        for (j, share) in proof_shares.iter().enumerate() {
            share
                .check_size(self.n, &self.bp_gens, j)
                .unwrap_or_else(|_| {
                    bad_shares.push(j);
                });
        }
        if !bad_shares.is_empty() {
            return Err(MpcError::MalformedProofShares { bad_shares });
        }
        let t_x: Scalar = proof_shares.iter().map(|ps| ps.t_x).sum();
        let t_x_blinding: Scalar = proof_shares.iter().map(|ps| ps.t_x_blinding).sum();
        let e_blinding: Scalar = proof_shares.iter().map(|ps| ps.e_blinding).sum();
        // Get a challenge value to combine statements for the IPP
        let mut input = self.poly_challenge.x.as_bytes().to_vec();
        input.extend_from_slice(self.poly_challenge.x.as_bytes());
        input.extend_from_slice(t_x_blinding.as_bytes());
        input.extend_from_slice(e_blinding.as_bytes());
        input.extend_from_slice(t_x.as_bytes());
        let mut w = [0u8; 32];
        keccak_256(&input, &mut w);
        // TODO: Monero checks if w is equal to zero and aborts if so (bulletproof.cc:720)
        let w = Scalar::from_bytes_mod_order(w);
        let Q = w * self.pc_gens.B;
        let G_factors: Vec<Scalar> = iter::repeat(Scalar::one()).take(self.n * self.m).collect();
        let H_factors: Vec<Scalar> = util::exp_iter(self.bit_challenge.y.invert())
            .take(self.n * self.m)
            .collect();
        let l_vec: Vec<Scalar> = proof_shares
            .iter()
            .flat_map(|ps| ps.l_vec.clone().into_iter())
            .collect();
        let r_vec: Vec<Scalar> = proof_shares
            .iter()
            .flat_map(|ps| ps.r_vec.clone().into_iter())
            .collect();
        let ipp_proof = inner_product_proof::InnerProductProof::create(
            &w,
            &Q,
            &G_factors,
            &H_factors,
            self.bp_gens.G(self.n, self.m).cloned().collect(),
            self.bp_gens.H(self.n, self.m).cloned().collect(),
            l_vec,
            r_vec,
        );
        Ok(RangeProof {
            A: self.A,
            S: self.S,
            T_1: self.T_1,
            T_2: self.T_2,
            t_x,
            t_x_blinding,
            e_blinding,
            ipp_proof,
        })
    }
fn assemble_shares ( & mut self , proof_shares : & [ ProofShare ] ) -> Result < RangeProof , MpcError > { if self . m != proof_shares . len ( ) { return Err ( MpcError :: WrongNumProofShares ) ; } // Validate lengths for each share let mut bad_shares = Vec :: < usize > :: new ( ) ; // no allocations until we append for ( j , share ) in proof_shares . iter ( ) . enumerate ( ) { share . check_size ( self . n , & self . bp_gens , j ) . unwrap_or_else ( | _ | { bad_shares . push ( j ) ; } ) ; } if ! bad_shares . is_empty ( ) { return Err ( MpcError :: MalformedProofShares { bad_shares } ) ; } let t_x : Scalar = proof_shares . iter ( ) . map ( | ps | ps . t_x ) . sum ( ) ; let t_x_blinding : Scalar = proof_shares . iter ( ) . map ( | ps | ps . t_x_blinding ) . sum ( ) ; let e_blinding : Scalar = proof_shares . iter ( ) . map ( | ps | ps . e_blinding ) . sum ( ) ; // Get a challenge value to combine statements for the IPP let mut input = self . poly_challenge . x . as_bytes ( ) . to_vec ( ) ; input . extend_from_slice ( self . poly_challenge . x . as_bytes ( ) ) ; input . extend_from_slice ( t_x_blinding . as_bytes ( ) ) ; input . extend_from_slice ( e_blinding . as_bytes ( ) ) ; input . extend_from_slice ( t_x . as_bytes ( ) ) ; let mut w = [ 0u8 ; 32 ] ; keccak_256 ( & input , & mut w ) ; // TODO: Monero checks if w is equal to zero and aborts if so (bulletproof.cc:720) let w = Scalar :: from_bytes_mod_order ( w ) ; let Q = w * self . pc_gens . B ; let G_factors : Vec < Scalar > = iter :: repeat ( Scalar :: one ( ) ) . take ( self . n * self . m ) . collect ( ) ; let H_factors : Vec < Scalar > = util :: exp_iter ( self . bit_challenge . y . invert ( ) ) . take ( self . n * self . m ) . collect ( ) ; let l_vec : Vec < Scalar > = proof_shares . iter ( ) . flat_map ( | ps | ps . l_vec . clone ( ) . into_iter ( ) ) . collect ( ) ; let r_vec : Vec < Scalar > = proof_shares . iter ( ) . flat_map ( | ps | ps . r_vec . clone ( ) . into_iter ( ) ) . collect ( ) ; let ipp_proof = inner_product_proof :: InnerProductProof :: create ( & w , & Q , & G_factors , & H_factors , self . bp_gens . G ( self . n , self . m ) . cloned ( ) . collect ( ) , self . bp_gens . H ( self . n , self . m ) . cloned ( ) . collect ( ) , l_vec , r_vec , ) ; Ok ( RangeProof { A : self . A , S : self . S , T_1 : self . T_1 , T_2 : self . T_2 , t_x , t_x_blinding , e_blinding , ipp_proof , } ) }
Assembles proof shares into an `RangeProof`.
Assembles proof shares into an ` RangeProof ` .
&mut self
proof_shares
&[ProofShare]
&mut self
proof_shares
&[ProofShare]