Skip to content

Commit

Permalink
Merge pull request #4 from Cybersecurity-LINKS/draft-irtf-cfrg-bbs-si…
Browse files Browse the repository at this point in the history
…gnatures-05

Update BBS+ and Blind BBS Signatures implemetations
  • Loading branch information
AlbertoSvg authored Mar 18, 2024
2 parents 95b359e + 5a92e1f commit 495393b
Show file tree
Hide file tree
Showing 137 changed files with 9,730 additions and 3,979 deletions.
11 changes: 8 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
[package]
name = "zkryptium"
version = "0.1.9"
version = "0.2.0"
edition = "2021"
license = "Apache-2.0"
authors = ["LINKS Foundation"]
description = "Rust crypto library for zero-knowledge proofs"
repository = "https://github.com/Cybersecurity-LINKS/zkryptium"
rust-version = "1.65"
keywords = [ "crypto", "signatures", "zero-knowledge", "bbs" ]
keywords = [ "crypto", "signatures", "zero-knowledge", "bbs", "blind-signature" ]
categories = [ "cryptography", "authentication" ]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand All @@ -18,6 +18,7 @@ zeroize = { version = "1.5" }
serde = { version = "1.0.25", default_feature = false, features = ["derive", "serde_derive"] }
serde_json = "1.0.59"
hex = "0.4.3"
thiserror = "1.0.30"

# cl03
rug = { version = "1.19.2", features = ["serde"], optional = true }
Expand All @@ -29,7 +30,7 @@ hkdf = "0.12.3"
digest = "0.10.6"

# bbsplus
bls12_381_plus = { version = "0.8.5", optional = true }
bls12_381_plus = { version = "0.8.13", optional = true }
ff = "0.13.0"
group = "0.10"
elliptic-curve = "0.13.4"
Expand All @@ -53,6 +54,10 @@ cl03 = ["dep:rug"]
bbsplus = ["dep:bls12_381_plus"]


[[example]]
name = "bbsplus_blind"
path = "examples/bbsplus_blind.rs"
features = ["bbsplus"]

[[example]]
name = "bbsplus"
Expand Down
22 changes: 8 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,18 @@

## Description

<!-- Provide a short description explaining the what, why, and how of your project. Use the following questions as a guide:
ZKryptium provides an implementation in accordance with:
* **BBS+**([draft-irtf-cfrg-bbs-signatures-05](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bbs-signatures-05)) signature scheme
* **Blind BBS Signatures** ([draft-kalos-bbs-blind-signatures-00](https://datatracker.ietf.org/doc/html/draft-kalos-bbs-blind-signatures-00))
* **CL2003** (https://link.springer.com/chapter/10.1007/3-540-36413-7_20) signature scheme

- What was your motivation?
- Why did you build this project? (Note: the answer is not "Because it was a homework assignment.")
- What problem does it solve?
- What did you learn? -->
ZKryptium offers implementations of the [BBS+](https://identity.foundation/bbs-signature/draft-irtf-cfrg-bbs-signatures.html) and [CL2003](https://link.springer.com/chapter/10.1007/3-540-36413-7_20) signature schemes, enabling the creation of zero-knowledge proofs for both signed attributes and signatures.
This library has been designed to expose cryptographic primitives, facilitating the development of a Verifiable Credentials (VCs) system capable of supporting:
- Anonymous Credentials
- Selective Disclosure Credentials

This library enables the creation of zero-knowledge proofs, exposing cryptographic primitives facilitating the development of a Verifiable Credentials (VCs) system capable of handling both Anonymous Credentials and Selective Disclosure Credentials.




## Getting Started
<!-- What are the steps required to install your project? Provide a step-by-step description of how to get the development environment running. -->

### Requirements

Expand All @@ -37,21 +33,19 @@ This library has been designed to expose cryptographic primitives, facilitating

```toml
[dependencies]
zkryptium = { version = "0.1.9", default-features = false, features = ["bbsplus"] }
zkryptium = { version = "0.2.0", default-features = false, features = ["bbsplus"] }
```

##### CL2003:
- see the **requirements** above

```toml
[dependencies]
zkryptium = { version = "0.1.9", default-features = false, features = ["cl03"] }
zkryptium = { version = "0.2.0", default-features = false, features = ["cl03"] }
```

### Examples

<!-- Provide instructions and examples for use. Include screenshots as needed. -->

Take a look at the [examples](https://github.com/Cybersecurity-LINKS/ZKryptium/tree/main/examples).

You can run the example based on the [BBS+](https://identity.foundation/bbs-signature/draft-irtf-cfrg-bbs-signatures.html) Signature Scheme with:
Expand Down
227 changes: 88 additions & 139 deletions examples/bbsplus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,176 +12,128 @@
// See the License for the specific language governing permissions and
// limitations under the License.


#[cfg(feature = "bbsplus")]
mod bbsplus_example {
use elliptic_curve::hash2curve::ExpandMsg;
use zkryptium::{utils::{message::BBSplusMessage, util::bbsplus_utils::generate_nonce}, keys::pair::KeyPair, bbsplus::{generators::Generators, ciphersuites::BbsCiphersuite}, schemes::algorithms::{BBSplus, Scheme, Ciphersuite}, schemes::generics::{Commitment, BlindSignature, PoKSignature, ZKPoK}};



pub(crate) fn bbsplus_main<S: Scheme>()
use rand::Rng;
use zkryptium::{
bbsplus::ciphersuites::BbsCiphersuite,
errors::Error,
keys::pair::KeyPair,
schemes::{
algorithms::{BBSplus, Scheme},
generics::{PoKSignature, Signature},
},
utils::util::bbsplus_utils::{generate_random_secret, get_messages_vec},
};

pub(crate) fn bbsplus_main<S: Scheme>() -> Result<(), Error>
where
S::Ciphersuite: BbsCiphersuite,
<S::Ciphersuite as BbsCiphersuite>::Expander: for<'a> ExpandMsg<'a>,
{
const MSGS: [&str; 3] = [
"9872ad089e452c7b6e283dfac2a80d58e8d0ff71cc4d5e310a1debdda4a45f02",
"87a8bd656d49ee07b8110e1d8fd4f1dcef6fb9bc368c492d9bc8c4f98a739ac6",
"96012096adda3f13dd4adbe4eea481a4c4b5717932b73b00e31807d3c5894b90",
];

const IKM: &str = "746869732d49532d6a7573742d616e2d546573742d494b4d2d746f2d67656e65726174652d246528724074232d6b6579";
const KEY_INFO: &str = "746869732d49532d736f6d652d6b65792d6d657461646174612d746f2d62652d757365642d696e2d746573742d6b65792d67656e";
const msgs: [&str; 3] = ["9872ad089e452c7b6e283dfac2a80d58e8d0ff71cc4d5e310a1debdda4a45f02", "87a8bd656d49ee07b8110e1d8fd4f1dcef6fb9bc368c492d9bc8c4f98a739ac6", "96012096adda3f13dd4adbe4eea481a4c4b5717932b73b00e31807d3c5894b90"];

log::info!("Messages: {:?}", msgs);

const header_hex: &str = "11223344556677889900aabbccddeeff";
let dst: Vec<u8> = hex::decode("4242535f424c53313233383147315f584d443a5348412d3235365f535357555f524f5f4d41505f4d53475f544f5f5343414c41525f41535f484153485f").unwrap();
let header = hex::decode(header_hex).unwrap();
let unrevealed_message_indexes = [1usize];
let revealed_message_indexes = [0usize, 2usize];

log::info!("Messages: {:?}", MSGS);

log::info!("Keypair Generation");
let issuer_keypair = KeyPair::<BBSplus<S::Ciphersuite>>::generate(
None,
Some(&hex::decode(&KEY_INFO).unwrap())
);
const HEADER_HEX: &str = "11223344556677889900aabbccddeeff";
let header = hex::decode(HEADER_HEX).unwrap();

let mut rng = rand::thread_rng();
let key_material: Vec<u8> = (0..S::Ciphersuite::IKM_LEN).map(|_| rng.gen()).collect();

log::info!("Keypair Generation");
let issuer_keypair =
KeyPair::<BBSplus<S::Ciphersuite>>::generate(&key_material, None, None)?;

let issuer_sk = issuer_keypair.private_key();
log::info!("SK: {}", hex::encode(issuer_sk.to_bytes()));
let issuer_pk = issuer_keypair.public_key();

log::info!("Computing Generators");

let generators = Generators::create::<S::Ciphersuite>(Some(issuer_pk), msgs.len()+2);
//Map Messages to Scalars

let msgs_scalars: Vec<BBSplusMessage> = msgs.iter().map(|m| BBSplusMessage::map_message_to_scalar_as_hash::<BBSplus<S::Ciphersuite>>(&hex::decode(m).unwrap(), Some(&dst))).collect();

log::info!("Computing pedersen commitment on messages");
let commitment = Commitment::<BBSplus<S::Ciphersuite>>::commit(&msgs_scalars, None, &issuer_pk, &unrevealed_message_indexes);


let unrevealed_msgs: Vec<BBSplusMessage> = msgs_scalars.iter().enumerate().filter_map(|(i, m)| {
if unrevealed_message_indexes.contains(&i) {
Some(*m)
} else {
None
}
}).collect();

let revealed_msgs: Vec<BBSplusMessage> = msgs_scalars.iter().enumerate().filter_map(|(i, m)| {
if !unrevealed_message_indexes.contains(&i) {
Some(*m)
} else {
None
}
}).collect();


//Holder receive nonce from Issuer
let nonce_issuer = generate_nonce();
log::info!("Generate Nonce...");
log::info!("Nonce: {}", hex::encode(&nonce_issuer));


log::info!("Computation of a Zero-Knowledge proof-of-knowledge of committed messages");
let zkpok = ZKPoK::<BBSplus<S::Ciphersuite>>::generate_proof(&unrevealed_msgs, commitment.bbsPlusCommitment(), &generators, &unrevealed_message_indexes, &nonce_issuer);


//Issuer compute blind signature
log::info!("Verification of the Zero-Knowledge proof and computation of a blind signature");
let blind_signature = BlindSignature::<BBSplus<S::Ciphersuite>>::blind_sign(&revealed_msgs, commitment.bbsPlusCommitment(), &zkpok, issuer_sk, issuer_pk, Some(&generators), &revealed_message_indexes, &unrevealed_message_indexes, &nonce_issuer, Some(&header));

if let Err(e) = &blind_signature {
println!("Error: {}", e);
}

assert!(blind_signature.is_ok(), "Blind Signature Error");

let blind_signature = blind_signature.unwrap();

//Holder unblind the signature
log::info!("Signature unblinding and verification...");
let unblind_signature = blind_signature.unblind_sign(commitment.bbsPlusCommitment());

let verify = unblind_signature.verify(issuer_pk, Some(&msgs_scalars), Some(&generators), Some(&header));

assert!(verify, "Unblinded Signature NOT VALID!");
log::info!("Signature is VALID!");
log::info!("PK: {}", hex::encode(issuer_pk.to_bytes()));

let messages: Vec<Vec<u8>> = MSGS.iter().map(|m| hex::decode(m).unwrap()).collect();
log::info!("Signature Computation...");
let signature = Signature::<BBSplus<S::Ciphersuite>>::sign(
Some(&messages),
issuer_sk,
issuer_pk,
Some(&header),
)
.unwrap();

assert!(
signature
.verify(issuer_pk, Some(&messages), Some(&header))
.is_ok(),
"Signature verification FAILED!"
);
log::info!("Signature is VALID");

//Holder receive nonce from Verifier
let nonce_verifier = generate_nonce();
let nonce_verifier = generate_random_secret(32);
log::info!("Generate Nonce...");
log::info!("Nonce: {}", hex::encode(&nonce_verifier));

let disclosed_indexes = [0usize, 2usize];

//Holder generates SPoK
log::info!("Computation of a Zero-Knowledge proof-of-knowledge of a signature");
let proof = PoKSignature::<BBSplus<S::Ciphersuite>>::proof_gen(unblind_signature.bbsPlusSignature(), &issuer_pk, Some(&msgs_scalars), Some(&generators), Some(&revealed_message_indexes), Some(&header), Some(&nonce_verifier), None);
log::info!("Proof of Knowledge of the Signature Generation...");
let proof = PoKSignature::<BBSplus<S::Ciphersuite>>::proof_gen(
issuer_pk,
&signature.to_bytes(),
Some(&header),
Some(&nonce_verifier),
Some(&messages),
Some(&disclosed_indexes),
)
.unwrap();

//Verifier verifies SPok
log::info!("Signature Proof of Knowledge verification...");
let proof_result = proof.proof_verify(&issuer_pk, Some(&revealed_msgs), Some(&generators), Some(&revealed_message_indexes), Some(&header), Some(&nonce_verifier));
assert!(proof_result, "Signature Proof of Knowledge Verification Failed!");
log::info!("Signature Proof of Knowledge is VALID!");

// Holder request update from Issuer

// Holder sends its Blinded Credential ad Commitment to Issuer

// Issuer verifies Blind Signature
let blind_signature_verification_res = blind_signature.verify(&revealed_msgs, commitment.bbsPlusCommitment(), issuer_pk, Some(&generators), &revealed_message_indexes, &unrevealed_message_indexes, Some(&header));

assert!(blind_signature_verification_res, "Blind Signature NOT Valid");

// Issuer update the Blind Signature


const new_message: &str = "8872ad089e452c7b6e283dfac2a80d58e8d0ff71cc4d5e310a1debdda4a45f05";
const update_index: usize = 0usize;


let new_message_scalar = BBSplusMessage::map_message_to_scalar_as_hash::<BBSplus<S::Ciphersuite>>(&hex::decode(new_message).unwrap(), Some(&dst));
let old_message_scalar = revealed_msgs.get(update_index).unwrap();

let new_blind_signature = blind_signature.update_signature(issuer_sk, issuer_pk, msgs_scalars.len(), old_message_scalar, &new_message_scalar, update_index);


// Issuer verifies Blind Signature with old messages
let blind_signature_verification_res = new_blind_signature.verify(&revealed_msgs, commitment.bbsPlusCommitment(), issuer_pk, Some(&generators), &revealed_message_indexes, &unrevealed_message_indexes, Some(&header));

assert!(!blind_signature_verification_res, "Blind Signature verification MUST fail!");

// Issuer verifies Blind Signature with new messages

let mut new_revealed_msgs = revealed_msgs.clone();
new_revealed_msgs[update_index] = new_message_scalar;

let blind_signature_verification_res = new_blind_signature.verify(&new_revealed_msgs, commitment.bbsPlusCommitment(), issuer_pk, Some(&generators), &revealed_message_indexes, &unrevealed_message_indexes, Some(&header));

assert!(blind_signature_verification_res, "Blind Signature NOT valid!");

let disclosed_messages = get_messages_vec(&messages, &disclosed_indexes);

log::info!("Proof of Knowledge of the Signature verification...");
let proof_result = proof
.proof_verify(
&issuer_pk,
Some(&disclosed_messages),
Some(&disclosed_indexes),
Some(&header),
Some(&nonce_verifier),
)
.is_ok();
assert!(
proof_result,
"Proof of Knowledge of the Signature Verification Failed!"
);
log::info!("Proof of Knowledge of the Signature is VALID!");

Ok(())
}

}

#[cfg(feature = "bbsplus")]
fn main() {

use std::env;
use zkryptium::schemes::algorithms::{BBS_BLS12381_SHA256, BBS_BLS12381_SHAKE256};
use crate::bbsplus_example::bbsplus_main;

use std::env;
use zkryptium::schemes::algorithms::{BbsBls12381Sha256, BbsBls12381Shake256};

dotenv::dotenv().ok();
env_logger::init();

let args: Vec<String> = env::args().collect();

if args.len() != 2 {
println!("Usage: {} <cipher_suite>
println!(
"Usage: {} <cipher_suite>
Ciphersuites:
- BLS12-381-SHA-256
- BLS12-381-SHAKE-256", args[0]);
- BLS12-381-SHAKE-256",
args[0]
);
return;
}

Expand All @@ -191,22 +143,19 @@ fn main() {
"BLS12-381-SHA-256" => {
println!("\n");
log::info!("Ciphersuite: BLS12-381-SHA-256");
bbsplus_main::<BBS_BLS12381_SHA256>();
let _ = bbsplus_main::<BbsBls12381Sha256>();
}
"BLS12-381-SHAKE-256" => {
println!("\n");
log::info!("Ciphersuite: BLS12-381-SHAKE-256");
bbsplus_main::<BBS_BLS12381_SHAKE256>();

let _ = bbsplus_main::<BbsBls12381Shake256>();
}
_ => {
println!("Unknown cipher suite: {}", cipher_suite);
// Handle other cipher suites or raise an error if necessary
}
}

}


#[cfg(not(feature = "bbsplus"))]
fn main() {}
fn main() {}
Loading

0 comments on commit 495393b

Please sign in to comment.