Feature/coconut hash (#3231)

* Hash over public attributes too

* Improve and fix api unit test

* Rename hash function
This commit is contained in:
Bogdan-Ștefan Neacşu
2023-03-28 15:08:54 +03:00
committed by GitHub
parent 956a264106
commit 6e72433f99
4 changed files with 35 additions and 57 deletions
+7 -5
View File
@@ -14,9 +14,10 @@ use itertools::izip;
use sha2::Sha256;
use crate::error::{CoconutError, Result};
use crate::scheme::issuance::compute_hash;
use crate::scheme::setup::Parameters;
use crate::scheme::VerificationKey;
use crate::utils::{hash_g1, try_deserialize_scalar, try_deserialize_scalar_vec};
use crate::utils::{try_deserialize_scalar, try_deserialize_scalar_vec};
use crate::Attribute;
// as per the reference python implementation
@@ -91,6 +92,7 @@ impl ProofCmCs {
commitments: &[G1Projective],
pedersen_commitments_openings: &[Scalar],
private_attributes: &[Attribute],
public_attributes: &[Attribute],
) -> Self {
// note: this is only called from `prepare_blind_sign` that already checks
// whether private attributes are non-empty and whether we don't have too many
@@ -104,7 +106,7 @@ impl ProofCmCs {
let witness_attributes = params.n_random_scalars(private_attributes.len());
// recompute h
let h = hash_g1(commitment.to_bytes());
let h = compute_hash(*commitment, public_attributes);
let hs_bytes = params
.gen_hs()
.iter()
@@ -186,7 +188,7 @@ impl ProofCmCs {
}
// recompute h
let h = hash_g1(commitment.to_bytes());
let h = compute_hash(*commitment, public_attributes);
let g1 = params.gen1();
let hs_bytes = params
@@ -531,7 +533,7 @@ mod tests {
let private_attributes = params.n_random_scalars(1);
// 0 public 1 private
let pi_s = ProofCmCs::construct(&params, &cm, &r, &cms, &rs, &private_attributes);
let pi_s = ProofCmCs::construct(&params, &cm, &r, &cms, &rs, &private_attributes, &[]);
let bytes = pi_s.to_bytes();
assert_eq!(ProofCmCs::from_bytes(&bytes).unwrap(), pi_s);
@@ -547,7 +549,7 @@ mod tests {
let private_attributes = params.n_random_scalars(2);
// 0 public 2 privates
let pi_s = ProofCmCs::construct(&params, &cm, &r, &cms, &rs, &private_attributes);
let pi_s = ProofCmCs::construct(&params, &cm, &r, &cms, &rs, &private_attributes, &[]);
let bytes = pi_s.to_bytes();
assert_eq!(ProofCmCs::from_bytes(&bytes).unwrap(), pi_s);
+10 -4
View File
@@ -201,8 +201,13 @@ pub fn compute_pedersen_commitments_for_private_attributes(
(commitments_openings, pedersen_commitments)
}
pub fn compute_commitment_hash(commitment: G1Projective) -> G1Projective {
hash_g1(commitment.to_bytes())
pub fn compute_hash(commitment: G1Projective, public_attributes: &[Attribute]) -> G1Projective {
let mut buff = Vec::new();
buff.extend_from_slice(commitment.to_bytes().as_ref());
for attr in public_attributes {
buff.extend_from_slice(attr.to_bytes().as_ref());
}
hash_g1(buff)
}
/// Builds cryptographic material required for blind sign.
@@ -230,7 +235,7 @@ pub fn prepare_blind_sign(
compute_attributes_commitment(params, private_attributes, public_attributes, hs);
// Compute the challenge as the commitment hash
let commitment_hash = compute_commitment_hash(commitment);
let commitment_hash = compute_hash(commitment, public_attributes);
let (pedersen_commitments_openings, pedersen_commitments) =
compute_pedersen_commitments_for_private_attributes(
@@ -246,6 +251,7 @@ pub fn prepare_blind_sign(
&pedersen_commitments,
&pedersen_commitments_openings,
private_attributes,
public_attributes,
);
Ok((
@@ -276,7 +282,7 @@ pub fn blind_sign(
}
// Verify the commitment hash
let h = hash_g1(blind_sign_request.commitment.to_bytes());
let h = compute_hash(blind_sign_request.commitment, public_attributes);
if !(h == blind_sign_request.commitment_hash) {
return Err(CoconutError::Issuance(
"Failed to verify the commitment hash".to_string(),
+2 -5
View File
@@ -237,14 +237,11 @@ impl SignatureShare {
#[cfg(test)]
mod tests {
use group::GroupEncoding;
use crate::hash_to_scalar;
use crate::scheme::aggregation::{aggregate_signatures, aggregate_verification_keys};
use crate::scheme::issuance::{blind_sign, prepare_blind_sign, sign};
use crate::scheme::issuance::{blind_sign, compute_hash, prepare_blind_sign, sign};
use crate::scheme::keygen::{keygen, ttp_keygen};
use crate::scheme::verification::{prove_bandwidth_credential, verify, verify_credential};
use crate::utils::hash_g1;
use super::*;
@@ -262,7 +259,7 @@ mod tests {
let wrong_commitment_opening = params.random_scalar();
let wrong_commitment = params.gen1() * wrong_commitment_opening;
let fake_commitment_hash = hash_g1(wrong_commitment.to_bytes());
let fake_commitment_hash = compute_hash(wrong_commitment, &[]);
let wrong_commitments_openings = params.n_random_scalars(private_attributes.len());
assert!(sig1
+16 -43
View File
@@ -23,9 +23,7 @@ use nym_credentials::coconut::params::{
use nym_crypto::shared_key::recompute_shared_key;
use nym_crypto::symmetric::stream_cipher;
use nymcoconut::tests::helpers::theta_from_keys_and_attributes;
use nymcoconut::{
prepare_blind_sign, ttp_keygen, Base58, BlindSignRequest, BlindedSignature, Parameters,
};
use nymcoconut::{prepare_blind_sign, ttp_keygen, Base58, BlindedSignature, Parameters};
use validator_client::nym_api::routes::{
API_VERSION, BANDWIDTH, COCONUT_BLIND_SIGN, COCONUT_ROUTES, COCONUT_VERIFY_BANDWIDTH_CREDENTIAL,
};
@@ -729,21 +727,16 @@ async fn blind_sign_correct() {
let params = Parameters::new(4).unwrap();
let mut rng = OsRng;
let identity_keypair = identity::KeyPair::new(&mut rng);
let encryption_keypair = encryption::KeyPair::new(&mut rng);
let voucher = BandwidthVoucher::new(
&params,
"1234".to_string(),
VOUCHER_INFO.to_string(),
tx_hash,
identity::PrivateKey::from_base58_string(
identity::KeyPair::new(&mut rng)
.private_key()
.to_base58_string(),
)
.unwrap(),
encryption::PrivateKey::from_bytes(
&encryption::KeyPair::new(&mut rng).private_key().to_bytes(),
)
.unwrap(),
identity::PrivateKey::from_base58_string(identity_keypair.private_key().to_base58_string())
.unwrap(),
encryption::PrivateKey::from_bytes(&encryption_keypair.private_key().to_bytes()).unwrap(),
);
let key_pair = ttp_keygen(&params, 1, 1).unwrap().remove(0);
@@ -768,13 +761,17 @@ async fn blind_sign_correct() {
},
Tag {
key: DEPOSIT_IDENTITY_KEY.parse().unwrap(),
value: "64auwDkWan7R8yH1Mwe9dS4qXgrDBCUNDg3Q4KFnd2P5"
value: identity_keypair
.public_key()
.to_base58_string()
.parse()
.unwrap(),
},
Tag {
key: DEPOSIT_ENCRYPTION_KEY.parse().unwrap(),
value: "HxnTpWTkgigSTAysVKLE8pEiUULHdTT1BxFfzfJvQRi6"
value: encryption_keypair
.public_key()
.to_base58_string()
.parse()
.unwrap(),
},
@@ -801,36 +798,12 @@ async fn blind_sign_correct() {
.await
.expect("valid rocket instance");
// hard-coded values, that generate a correct signature
let blind_sign_req = BlindSignRequest::from_bytes(&[
176, 113, 19, 237, 218, 252, 113, 20, 225, 238, 59, 88, 217, 45, 233, 178, 65, 28, 242, 0,
222, 48, 110, 216, 26, 111, 51, 235, 61, 74, 200, 15, 130, 245, 45, 170, 155, 190, 156, 77,
180, 142, 29, 63, 15, 224, 150, 31, 139, 24, 65, 175, 143, 153, 11, 203, 33, 16, 152, 22,
221, 203, 99, 233, 208, 142, 161, 194, 46, 227, 177, 96, 119, 30, 175, 69, 104, 14, 2, 191,
26, 94, 30, 165, 15, 28, 40, 176, 1, 78, 253, 79, 20, 137, 102, 74, 2, 0, 0, 0, 0, 0, 0, 0,
131, 133, 112, 115, 53, 98, 58, 166, 240, 70, 185, 210, 203, 12, 114, 66, 180, 38, 139, 12,
187, 45, 250, 201, 68, 102, 159, 172, 218, 124, 151, 23, 172, 18, 216, 122, 246, 7, 185,
76, 20, 167, 123, 122, 152, 241, 175, 226, 176, 8, 170, 70, 140, 252, 36, 130, 67, 204,
111, 116, 107, 92, 200, 77, 252, 31, 138, 18, 10, 215, 165, 243, 95, 199, 193, 61, 200,
187, 22, 198, 109, 213, 145, 71, 171, 132, 174, 68, 105, 248, 0, 115, 50, 55, 199, 84, 67,
16, 125, 216, 250, 154, 115, 174, 9, 206, 44, 88, 63, 163, 124, 10, 239, 64, 158, 191, 27,
169, 177, 194, 223, 142, 202, 206, 189, 122, 123, 91, 171, 15, 40, 192, 148, 75, 174, 24,
116, 229, 127, 170, 110, 183, 151, 2, 118, 168, 22, 113, 87, 237, 91, 228, 249, 120, 114,
255, 53, 175, 245, 39, 2, 0, 0, 0, 0, 0, 0, 0, 225, 45, 230, 25, 62, 202, 96, 166, 171,
241, 206, 137, 254, 51, 154, 255, 122, 130, 107, 54, 5, 206, 207, 120, 193, 214, 64, 10,
111, 195, 86, 55, 201, 36, 10, 18, 154, 158, 183, 87, 185, 59, 228, 89, 134, 193, 217, 188,
64, 164, 249, 21, 248, 20, 207, 58, 31, 10, 19, 176, 246, 150, 45, 48, 2, 0, 0, 0, 0, 0, 0,
0, 173, 60, 65, 209, 100, 114, 138, 186, 158, 150, 109, 230, 111, 86, 101, 72, 194, 237,
173, 195, 139, 175, 238, 25, 169, 18, 188, 75, 77, 54, 111, 20, 115, 235, 195, 2, 123, 133,
164, 81, 15, 45, 11, 84, 139, 38, 8, 224, 197, 181, 95, 147, 49, 77, 193, 207, 52, 141,
195, 195, 66, 137, 17, 32,
])
.unwrap();
let request_body = BlindSignRequestBody::new(
&blind_sign_req,
voucher.blind_sign_request(),
tx_hash.to_string(),
"gSFgpma5GAVMcsmZwKieqGNHNd3dPzcfa8eT2Qn2LoBccSeyiJdphREbNrkuh5XWxMe2hUsranaYzLro48L9Qhd"
.to_string(),
voucher
.sign(voucher.blind_sign_request())
.to_base58_string(),
&voucher.get_public_attributes(),
voucher.get_public_attributes_plain(),
4,