|  | @@ -28,6 +28,11 @@ mpz_class log2(mpz_class x)
 | 
	
		
			
				|  |  |      return retval;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +mpz_class bit(mpz_class x)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    return x > 0 ? 1 : 0;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  /********************
 | 
	
		
			
				|  |  |   * PUBLIC FUNCTIONS *
 | 
	
		
			
				|  |  |   ********************/
 | 
	
	
		
			
				|  | @@ -84,29 +89,37 @@ Curvepoint PrsonaClient::get_short_term_public_key(Proof &pi) const
 | 
	
		
			
				|  |  |   * SERVER INTERACTIONS
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -// Generate a new vote vector to give to the servers
 | 
	
		
			
				|  |  | -// (@replace controls which votes are actually being updated and which are not)
 | 
	
		
			
				|  |  | +/* Generate a new vote vector to give to the servers
 | 
	
		
			
				|  |  | + * @replaces controls which votes are actually being updated and which are not
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * You may really want to make currentEncryptedVotes a member variable, 
 | 
	
		
			
				|  |  | + * but it doesn't behave correctly when adding new clients after this one. */
 | 
	
		
			
				|  |  |  std::vector<CurveBipoint> PrsonaClient::make_votes(
 | 
	
		
			
				|  |  |      Proof& pi,
 | 
	
		
			
				|  |  | -    const std::vector<Scalar>& vote,
 | 
	
		
			
				|  |  | -    const std::vector<bool>& replace)
 | 
	
		
			
				|  |  | +    const std::vector<CurveBipoint>& currentEncryptedVotes,
 | 
	
		
			
				|  |  | +    const std::vector<Scalar>& votes,
 | 
	
		
			
				|  |  | +    const std::vector<bool>& replaces)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |      std::vector<CurveBipoint> retval;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    for (size_t i = 0; i < vote.size(); i++)
 | 
	
		
			
				|  |  | +    if (!verify_valid_votes_proof(pi, currentEncryptedVotes))
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        std::cerr << "Could not verify proof of valid votes." << std::endl;
 | 
	
		
			
				|  |  | +        return retval;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    for (size_t i = 0; i < votes.size(); i++)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |          CurveBipoint currScore;
 | 
	
		
			
				|  |  | -        if (replace[i])
 | 
	
		
			
				|  |  | -            serverPublicKey.encrypt(currScore, vote[i]);
 | 
	
		
			
				|  |  | +        if (replaces[i])
 | 
	
		
			
				|  |  | +            serverPublicKey.encrypt(currScore, votes[i]);
 | 
	
		
			
				|  |  |          else
 | 
	
		
			
				|  |  |              currScore = serverPublicKey.rerandomize(currentEncryptedVotes[i]);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          retval.push_back(currScore);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    currentEncryptedVotes = retval;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    pi = generate_vote_proof(retval, vote);
 | 
	
		
			
				|  |  | +    pi = generate_vote_proof(retval, votes);
 | 
	
		
			
				|  |  |      return retval;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -130,32 +143,21 @@ void PrsonaClient::receive_vote_tally(
 | 
	
		
			
				|  |  |      decrypt_score(score);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -// Receive a new encrypted vote vector from the servers (each epoch)
 | 
	
		
			
				|  |  | -void PrsonaClient::receive_encrypted_votes(
 | 
	
		
			
				|  |  | -    const Proof& pi, const std::vector<CurveBipoint>& votes)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -    if (!verify_valid_votes_proof(pi, votes))
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -        std::cerr << "Could not verify proof of valid votes." << std::endl;
 | 
	
		
			
				|  |  | -        return;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    currentEncryptedVotes = votes;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  /*
 | 
	
		
			
				|  |  |   * REPUTATION PROOFS
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -// TO BE UPDATED WITH THING IAN SHOWED ME IN MEETING FOR DISJUNCTION
 | 
	
		
			
				|  |  | +// A pretty straightforward range proof (generation)
 | 
	
		
			
				|  |  |  std::vector<Proof> PrsonaClient::generate_reputation_proof(
 | 
	
		
			
				|  |  |      const Scalar& threshold) const
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |      std::vector<Proof> retval;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    // Don't even try if the user asks to make an illegitimate proof
 | 
	
		
			
				|  |  |      if (threshold > currentScore)
 | 
	
		
			
				|  |  |          return retval;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    // Base case
 | 
	
		
			
				|  |  |      if (!CLIENT_IS_MALICIOUS)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |          Proof currProof;
 | 
	
	
		
			
				|  | @@ -165,78 +167,79 @@ std::vector<Proof> PrsonaClient::generate_reputation_proof(
 | 
	
		
			
				|  |  |          return retval;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    // We really have two consecutive proofs in a junction.
 | 
	
		
			
				|  |  | +    // The first is to prove that we are the stpk we claim we are
 | 
	
		
			
				|  |  |      retval.push_back(generate_ownership_proof());
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    // The value we're actually using in our proof
 | 
	
		
			
				|  |  |      mpz_class proofVal = currentScore.curveSub(threshold).toInt();
 | 
	
		
			
				|  |  | -    mpz_class proofBits = log2(currentEncryptedVotes.size() * MAX_ALLOWED_VOTE - threshold.toInt());
 | 
	
		
			
				|  |  | +    // Top of the range in our proof determined by what scores are even possible
 | 
	
		
			
				|  |  | +    mpz_class proofBits =
 | 
	
		
			
				|  |  | +        log2(
 | 
	
		
			
				|  |  | +            servers->get_num_clients() * MAX_ALLOWED_VOTE -
 | 
	
		
			
				|  |  | +            threshold.toInt());
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    // Don't risk a situation that would divulge our private key
 | 
	
		
			
				|  |  | +    if (proofBits <= 1)
 | 
	
		
			
				|  |  | +        proofBits = 2;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    // This seems weird, but remember our base is A_t^r, not g^t
 | 
	
		
			
				|  |  |      std::vector<Scalar> masksPerBit;
 | 
	
		
			
				|  |  | -    masksPerBit.push_back(Scalar());
 | 
	
		
			
				|  |  | +    masksPerBit.push_back(inversePrivateKey);
 | 
	
		
			
				|  |  |      for (size_t i = 1; i < proofBits; i++)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |          Scalar currMask;
 | 
	
		
			
				|  |  |          currMask.set_random();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          masksPerBit.push_back(currMask);
 | 
	
		
			
				|  |  | -        masksPerBit[0] = masksPerBit[0].curveSub(currMask.curveMult(Scalar(1 << i)));
 | 
	
		
			
				|  |  | +        masksPerBit[0] =
 | 
	
		
			
				|  |  | +            masksPerBit[0].curveSub(currMask.curveMult(Scalar(1 << i)));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    // Taken from Fig. 1 in https://eprint.iacr.org/2014/764.pdf
 | 
	
		
			
				|  |  |      for (size_t i = 0; i < proofBits; i++)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |          Proof currProof;
 | 
	
		
			
				|  |  | -        std::stringstream oracleInput;
 | 
	
		
			
				|  |  | -        oracleInput << currentFreshGenerator << EL_GAMAL_BLIND_GENERATOR;
 | 
	
		
			
				|  |  | +        Curvepoint g, h, c, c_a, c_b;
 | 
	
		
			
				|  |  | +        g = currentEncryptedScore.mask;
 | 
	
		
			
				|  |  | +        h = EL_GAMAL_BLIND_GENERATOR;
 | 
	
		
			
				|  |  |      
 | 
	
		
			
				|  |  | -        mpz_class currBit = proofVal & (1 << i);
 | 
	
		
			
				|  |  | +        mpz_class currBit = bit(proofVal & (1 << i));
 | 
	
		
			
				|  |  | +        Scalar a, s, t, m, r;
 | 
	
		
			
				|  |  | +        a.set_random();
 | 
	
		
			
				|  |  | +        s.set_random();
 | 
	
		
			
				|  |  | +        t.set_random();
 | 
	
		
			
				|  |  | +        m = Scalar(currBit);
 | 
	
		
			
				|  |  | +        r = masksPerBit[i];
 | 
	
		
			
				|  |  |          
 | 
	
		
			
				|  |  | -        Curvepoint currentCommitment = currentFreshGenerator * masksPerBit[i] + EL_GAMAL_BLIND_GENERATOR * Scalar(currBit);
 | 
	
		
			
				|  |  | -        currProof.partialUniversals.push_back(currentCommitment);
 | 
	
		
			
				|  |  | -        oracleInput << currentCommitment;
 | 
	
		
			
				|  |  | +        c = g * r + h * m;
 | 
	
		
			
				|  |  | +        currProof.partialUniversals.push_back(c);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        if (currBit)
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            Scalar u_0, c, c_0, c_1, z_0, z_1;
 | 
	
		
			
				|  |  | -            u_0.set_random();
 | 
	
		
			
				|  |  | -            c_1.set_random();
 | 
	
		
			
				|  |  | -            z_1.set_random();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            Curvepoint U_0 = currentFreshGenerator * u_0;
 | 
	
		
			
				|  |  | -            Curvepoint U_1 = currentFreshGenerator * z_1 - currentCommitment * c_1 + EL_GAMAL_BLIND_GENERATOR;
 | 
	
		
			
				|  |  | -            currProof.initParts.push_back(U_0);
 | 
	
		
			
				|  |  | -            currProof.initParts.push_back(U_1);
 | 
	
		
			
				|  |  | -            oracleInput << U_0 << U_1;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            c = oracle(oracleInput.str());
 | 
	
		
			
				|  |  | -            c_0 = c.curveSub(c_1);
 | 
	
		
			
				|  |  | -            z_0 = c_0.curveMult(masksPerBit[i]).curveAdd(u_0);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            currProof.challengeParts.push_back(c_0);
 | 
	
		
			
				|  |  | -            currProof.challengeParts.push_back(c_1);
 | 
	
		
			
				|  |  | -            currProof.responseParts.push_back(z_0);
 | 
	
		
			
				|  |  | -            currProof.responseParts.push_back(z_1);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        else
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            Scalar u_1, c, c_0, c_1, z_0, z_1;
 | 
	
		
			
				|  |  | -            u_1.set_random();
 | 
	
		
			
				|  |  | -            c_0.set_random();
 | 
	
		
			
				|  |  | -            z_0.set_random();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            Curvepoint U_0 = currentFreshGenerator * z_0 - currentCommitment * c_0;
 | 
	
		
			
				|  |  | -            Curvepoint U_1 = currentFreshGenerator * u_1;
 | 
	
		
			
				|  |  | -            currProof.initParts.push_back(U_0);
 | 
	
		
			
				|  |  | -            currProof.initParts.push_back(U_1);
 | 
	
		
			
				|  |  | -            oracleInput << U_0 << U_1;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            c = oracle(oracleInput.str());
 | 
	
		
			
				|  |  | -            c_1 = c.curveSub(c_0);
 | 
	
		
			
				|  |  | -            z_1 = c_1.curveMult(masksPerBit[i]).curveAdd(u_1);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            currProof.challengeParts.push_back(c_0);
 | 
	
		
			
				|  |  | -            currProof.challengeParts.push_back(c_1);
 | 
	
		
			
				|  |  | -            currProof.responseParts.push_back(z_0);
 | 
	
		
			
				|  |  | -            currProof.responseParts.push_back(z_1);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +        c_a = g * s + h * a;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        Scalar am = a.curveMult(m);
 | 
	
		
			
				|  |  | +        c_b = g * t + h * am;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        std::stringstream oracleInput;
 | 
	
		
			
				|  |  | +        oracleInput << g << h << c << c_a << c_b;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        Scalar x = oracle(oracleInput.str());
 | 
	
		
			
				|  |  | +        currProof.challengeParts.push_back(x);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        Scalar f, z_a, z_b;
 | 
	
		
			
				|  |  | +        Scalar mx = m.curveMult(x);
 | 
	
		
			
				|  |  | +        f = mx.curveAdd(a);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        Scalar rx = r.curveMult(x);
 | 
	
		
			
				|  |  | +        z_a = rx.curveAdd(s);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        Scalar x_f = x.curveSub(f);
 | 
	
		
			
				|  |  | +        Scalar r_x_f = r.curveMult(x_f);
 | 
	
		
			
				|  |  | +        z_b = r_x_f.curveAdd(t);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        currProof.responseParts.push_back(f);
 | 
	
		
			
				|  |  | +        currProof.responseParts.push_back(z_a);
 | 
	
		
			
				|  |  | +        currProof.responseParts.push_back(z_b);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          retval.push_back(currProof);
 | 
	
		
			
				|  |  |      }
 | 
	
	
		
			
				|  | @@ -244,56 +247,90 @@ std::vector<Proof> PrsonaClient::generate_reputation_proof(
 | 
	
		
			
				|  |  |      return retval;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -// TO BE UPDATED WITH THING IAN SHOWED ME IN MEETING FOR DISJUNCTION
 | 
	
		
			
				|  |  | +// A pretty straightforward range proof (verification)
 | 
	
		
			
				|  |  |  bool PrsonaClient::verify_reputation_proof(
 | 
	
		
			
				|  |  |      const std::vector<Proof>& pi,
 | 
	
		
			
				|  |  |      const Curvepoint& shortTermPublicKey,
 | 
	
		
			
				|  |  |      const Scalar& threshold) const
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | +    // Reject outright if there's no proof to check
 | 
	
		
			
				|  |  |      if (pi.empty())
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        std::cerr << "Proof was empty, aborting." << std::endl;
 | 
	
		
			
				|  |  |          return false;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    // Base case
 | 
	
		
			
				|  |  |      if (!CLIENT_IS_MALICIOUS)
 | 
	
		
			
				|  |  |          return pi[0].basic == "PROOF";
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    // User should be able to prove they are who they say they are
 | 
	
		
			
				|  |  |      if (!verify_ownership_proof(pi[0], shortTermPublicKey))
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        std::cerr << "Schnorr proof failed, aborting." << std::endl;
 | 
	
		
			
				|  |  | +        return false;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Get the encrypted score in question from the servers
 | 
	
		
			
				|  |  | +    Proof serverProof;
 | 
	
		
			
				|  |  | +    EGCiphertext encryptedScore =
 | 
	
		
			
				|  |  | +        servers->get_current_tally(serverProof, shortTermPublicKey);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Rough for the prover but if the server messes up,
 | 
	
		
			
				|  |  | +    // no way to prove the thing anyways
 | 
	
		
			
				|  |  | +    if (!verify_valid_tally_proof(serverProof, encryptedScore))
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        std::cerr << "Server error prevented proof from working, aborting." << std::endl;
 | 
	
		
			
				|  |  |          return false;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    // X is the thing we're going to be checking in on throughout
 | 
	
		
			
				|  |  | +    // to try to get our score commitment back in the end.
 | 
	
		
			
				|  |  |      Curvepoint X;
 | 
	
		
			
				|  |  |      for (size_t i = 1; i < pi.size(); i++)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -        X = X + pi[i].partialUniversals[0] * Scalar(1 << (i - 1));
 | 
	
		
			
				|  |  | +        Curvepoint c, g, h;
 | 
	
		
			
				|  |  | +        c = pi[i].partialUniversals[0];
 | 
	
		
			
				|  |  | +        g = encryptedScore.mask;
 | 
	
		
			
				|  |  | +        h = EL_GAMAL_BLIND_GENERATOR;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        std::stringstream oracleInput;
 | 
	
		
			
				|  |  | -        oracleInput << currentFreshGenerator << EL_GAMAL_BLIND_GENERATOR << pi[i].partialUniversals[0];
 | 
	
		
			
				|  |  | -        oracleInput << pi[i].initParts[0] << pi[i].initParts[1];
 | 
	
		
			
				|  |  | +        X = X + c * Scalar(1 << (i - 1));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        Scalar c = oracle(oracleInput.str());
 | 
	
		
			
				|  |  | +        Scalar x, f, z_a, z_b;
 | 
	
		
			
				|  |  | +        x = pi[i].challengeParts[0];
 | 
	
		
			
				|  |  | +        f = pi[i].responseParts[0];
 | 
	
		
			
				|  |  | +        z_a = pi[i].responseParts[1];
 | 
	
		
			
				|  |  | +        z_b = pi[i].responseParts[2];
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        if (c != pi[i].challengeParts[0] + pi[i].challengeParts[1])
 | 
	
		
			
				|  |  | -            return false;
 | 
	
		
			
				|  |  | +        // Taken from Fig. 1 in https://eprint.iacr.org/2014/764.pdf
 | 
	
		
			
				|  |  | +        Curvepoint c_a, c_b;
 | 
	
		
			
				|  |  | +        c_a = g * z_a + h * f - c * x;
 | 
	
		
			
				|  |  | +        Scalar x_f = x.curveSub(f);
 | 
	
		
			
				|  |  | +        c_b = g * z_b - c * x_f;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        if (currentFreshGenerator * pi[i].responseParts[0] != pi[i].initParts[0] + pi[i].partialUniversals[0] * pi[i].challengeParts[0])
 | 
	
		
			
				|  |  | -            return false;
 | 
	
		
			
				|  |  | +        std::stringstream oracleInput;
 | 
	
		
			
				|  |  | +        oracleInput << g << h << c << c_a << c_b;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        if (currentFreshGenerator * pi[i].responseParts[1] != pi[i].initParts[1] + pi[i].partialUniversals[0] * pi[i].challengeParts[1] - EL_GAMAL_BLIND_GENERATOR)
 | 
	
		
			
				|  |  | +        if (oracle(oracleInput.str()) != pi[i].challengeParts[0])
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            std::cerr << "0 or 1 proof failed at index " << i << " of " << pi.size() - 1 << ", aborting." << std::endl;
 | 
	
		
			
				|  |  |              return false;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    Proof serverProof;
 | 
	
		
			
				|  |  | -    EGCiphertext encryptedScore = servers->get_current_tally(serverProof, shortTermPublicKey);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    if (!verify_valid_tally_proof(serverProof, encryptedScore))
 | 
	
		
			
				|  |  | -        return false;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |      Scalar negThreshold;
 | 
	
		
			
				|  |  |      negThreshold = Scalar(0).curveSub(threshold);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    Curvepoint scoreCommitment = encryptedScore.encryptedMessage + EL_GAMAL_BLIND_GENERATOR * negThreshold;
 | 
	
		
			
				|  |  | -    if (X != scoreCommitment)
 | 
	
		
			
				|  |  | -        return false;
 | 
	
		
			
				|  |  | +    Curvepoint scoreCommitment =
 | 
	
		
			
				|  |  | +        encryptedScore.encryptedMessage +
 | 
	
		
			
				|  |  | +        EL_GAMAL_BLIND_GENERATOR * negThreshold;
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    return X == scoreCommitment;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    return true;
 | 
	
		
			
				|  |  | +Scalar PrsonaClient::get_score() const
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    return currentScore;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /*********************
 | 
	
	
		
			
				|  | @@ -364,7 +401,7 @@ Proof PrsonaClient::generate_ownership_proof() const
 | 
	
		
			
				|  |  |      Scalar z = r.curveAdd(c.curveMult(longTermPrivateKey));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      retval.basic = "PROOF";
 | 
	
		
			
				|  |  | -    retval.initParts.push_back(u);
 | 
	
		
			
				|  |  | +    retval.challengeParts.push_back(c);
 | 
	
		
			
				|  |  |      retval.responseParts.push_back(z);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      return retval;
 | 
	
	
		
			
				|  | @@ -377,15 +414,15 @@ bool PrsonaClient::verify_ownership_proof(
 | 
	
		
			
				|  |  |      if (!CLIENT_IS_MALICIOUS)
 | 
	
		
			
				|  |  |          return pi.basic == "PROOF";
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    Curvepoint u = pi.initParts[0];
 | 
	
		
			
				|  |  | +    Scalar c = pi.challengeParts[0];
 | 
	
		
			
				|  |  | +    Scalar z = pi.responseParts[0];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    Curvepoint u = currentFreshGenerator * z - shortTermPublicKey * c;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      std::stringstream oracleInput;
 | 
	
		
			
				|  |  |      oracleInput << currentFreshGenerator << shortTermPublicKey << u;
 | 
	
		
			
				|  |  | -    Scalar c = oracle(oracleInput.str());
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    Scalar z = pi.responseParts[0];
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    return (currentFreshGenerator * z) == (shortTermPublicKey * c + u);
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    return c == oracle(oracleInput.str());
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /*
 |