Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 16 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,27 @@ Anoncreds-rs exposes three main parts: [`issuer`](./src/services/issuer.rs),

### Issuer

- Create a [schema](https://hyperledger.github.io/anoncreds-spec/#schema-publisher-publish-schema-object)
- Create a [credential definition](https://hyperledger.github.io/anoncreds-spec/#issuer-create-and-publish-credential-definition-object)
- Create a [revocation registry definition](https://hyperledger.github.io/anoncreds-spec/#issuer-create-and-publish-revocation-registry-objects)
- Create a [revocation status list](https://hyperledger.github.io/anoncreds-spec/#publishing-the-initial-initial-revocation-status-list-object)
- Update a [revocation status list](https://hyperledger.github.io/anoncreds-spec/#publishing-the-initial-initial-revocation-status-list-object)
- Update a [revocation status list](https://hyperledger.github.io/anoncreds-spec/#publishing-the-initial-initial-revocation-status-list-object)'s timestamp
- Create a [credential offer](https://hyperledger.github.io/anoncreds-spec/#credential-offer)
- Create a [credential](https://hyperledger.github.io/anoncreds-spec/#issue-credential)
- Create a [schema](https://hyperledger.github.io/anoncreds-spec/#schema-publisher-publish-schema-object)
- Create a [credential definition](https://hyperledger.github.io/anoncreds-spec/#issuer-create-and-publish-credential-definition-object)
- Create a [revocation registry definition](https://hyperledger.github.io/anoncreds-spec/#issuer-create-and-publish-revocation-registry-objects)
- Create a [revocation status list](https://hyperledger.github.io/anoncreds-spec/#publishing-the-initial-initial-revocation-status-list-object)
- Update a [revocation status list](https://hyperledger.github.io/anoncreds-spec/#publishing-the-initial-initial-revocation-status-list-object)
- Update a [revocation status list](https://hyperledger.github.io/anoncreds-spec/#publishing-the-initial-initial-revocation-status-list-object)'s timestamp
- Create a [credential offer](https://hyperledger.github.io/anoncreds-spec/#credential-offer)
- Create a [credential](https://hyperledger.github.io/anoncreds-spec/#issue-credential)

### Prover / Holder

- Create a [credential request](https://hyperledger.github.io/anoncreds-spec/#credential-request)
- Process an incoming [credential](https://hyperledger.github.io/anoncreds-spec/#receiving-a-credential)
- Create a [presentation](https://hyperledger.github.io/anoncreds-spec/#generate-presentation)
- Create, and update, a revocation state
- Create, and update, a revocation state with a witness
- Create a [credential request](https://hyperledger.github.io/anoncreds-spec/#credential-request)
- Process an incoming [credential](https://hyperledger.github.io/anoncreds-spec/#receiving-a-credential)
- Create a [presentation](https://hyperledger.github.io/anoncreds-spec/#generate-presentation)
- Create, and update, a revocation state
- Create, and update, a revocation state with a witness

### Verifier

- [Verify a presentation](https://hyperledger.github.io/anoncreds-spec/#verify-presentation)
- generate a nonce
- [Verify a presentation](https://hyperledger.github.io/anoncreds-spec/#verify-presentation)
- generate a nonce

## Wrappers

Expand All @@ -51,6 +51,7 @@ Anoncreds is, soon, available as a standalone library in Rust, but also via wrap
| Node.js | [javascript](https://github.com/hyperledger/anoncreds-wrapper-javascript/tree/main/packages/anoncreds-nodejs) | ✅ |
| React Native | [javascript](https://github.com/hyperledger/anoncreds-wrapper-javascript/tree/main/packages/anoncreds-react-native) | ✅ |
| Python | [python](https://github.com/hyperledger/anoncreds-rs/tree/main/wrappers/python) | ✅ |
| .net | [.net](https://github.com/hyperledger/anoncreds-rs/tree/main/wrappers/dotnet) | ✅ |

## Credit

Expand Down
75 changes: 72 additions & 3 deletions src/ffi/presentation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use super::util::{FfiList, FfiStrList};
use crate::data_types::cred_def::{CredentialDefinition, CredentialDefinitionId};
use crate::data_types::link_secret::LinkSecret;
use crate::data_types::presentation::Presentation;
use crate::data_types::pres_request::PresentationRequest;
use crate::data_types::rev_reg_def::RevocationRegistryDefinition;
use crate::data_types::rev_reg_def::RevocationRegistryDefinitionId;
use crate::data_types::rev_status_list::RevocationStatusList;
Expand Down Expand Up @@ -75,26 +76,50 @@ pub extern "C" fn anoncreds_create_presentation(
presentation_p: *mut ObjectHandle,
) -> ErrorCode {
catch_error(|| {
eprintln!("=== CREATE_PRESENTATION FFI START ===");
Copy link

Copilot AI Sep 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug print statements (eprintln!) should be removed from production code or replaced with proper logging using trace! or debug! macros for consistency with the existing codebase.

Copilot uses AI. Check for mistakes.
check_useful_c_ptr!(presentation_p);

eprintln!("Loading link_secret...");
let link_secret = _link_secret(link_secret)?;
eprintln!("Link secret loaded successfully");
Copy link

Copilot AI Sep 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug print statements (eprintln!) should be removed from production code or replaced with proper logging using trace! or debug! macros for consistency with the existing codebase.

Copilot uses AI. Check for mistakes.

eprintln!("Processing self-attested attributes...");
let self_attested = _self_attested(self_attest_names, self_attest_values)?;
eprintln!("Self-attested attributes processed successfully");

eprintln!("Preparing credential definitions...");
let cred_defs = _prepare_cred_defs(cred_defs, cred_def_ids)?;
eprintln!("Credential definitions prepared: {} entries", cred_defs.len());

eprintln!("Preparing schemas...");
let schemas = _prepare_schemas(schemas, schema_ids)?;
eprintln!("Schemas prepared: {} entries", schemas.len());

eprintln!("Loading credentials...");
let credentials = _credentials(credentials)?;
eprintln!("Credentials loaded: {} entries", credentials.len());

eprintln!("Creating present credentials structure...");
let present_creds = _present_credentials(&credentials, credentials_prove)?;
eprintln!("Present credentials created successfully");

eprintln!("About to call core create_presentation function...");
let pres_req_binding = pres_req.load()?;
let pres_req_obj: &PresentationRequest = pres_req_binding.cast_ref()?;
eprintln!("Pres_req nonce during creation: {:?}", pres_req_obj.value().nonce);
let presentation = create_presentation(
pres_req.load()?.cast_ref()?,
pres_req_obj,
present_creds,
self_attested,
&link_secret,
&schemas,
&cred_defs,
)?;
eprintln!("Core create_presentation completed successfully");

let presentation = ObjectHandle::create(presentation)?;
unsafe { *presentation_p = presentation };
eprintln!("=== CREATE_PRESENTATION FFI END - SUCCESS ===");
Ok(())
})
}
Expand Down Expand Up @@ -158,23 +183,67 @@ pub extern "C" fn anoncreds_verify_presentation(
result_p: *mut i8,
) -> ErrorCode {
catch_error(|| {
eprintln!("=== RUST VERIFY PRESENTATION DEBUG ===");
eprintln!("Input parameters:");
eprintln!(" presentation handle: {:?}", presentation);
eprintln!(" pres_req handle: {:?}", pres_req);
eprintln!(" schemas count: {}", schemas.len());
eprintln!(" schema_ids count: {}", schema_ids.len());
eprintln!(" cred_defs count: {}", cred_defs.len());
eprintln!(" cred_def_ids count: {}", cred_def_ids.len());

eprintln!("Schema IDs received:");
for (i, schema_id) in schema_ids.as_slice().iter().enumerate() {
if let Some(id_str) = schema_id.as_opt_str() {
eprintln!(" [{}]: '{}'", i, id_str);
}
}

eprintln!("CredDef IDs received:");
for (i, cred_def_id) in cred_def_ids.as_slice().iter().enumerate() {
if let Some(id_str) = cred_def_id.as_opt_str() {
eprintln!(" [{}]: '{}'", i, id_str);
}
}

let cred_defs = _prepare_cred_defs(cred_defs, cred_def_ids)?;
eprintln!("Prepared cred_defs: {} entries", cred_defs.len());
for (id, _) in &cred_defs {
eprintln!(" CredDef ID: '{}'", id);
}

let schemas = _prepare_schemas(schemas, schema_ids)?;
eprintln!("Prepared schemas: {} entries", schemas.len());
for (id, _) in &schemas {
eprintln!(" Schema ID: '{}'", id);
}

let rev_reg_defs = _rev_reg_defs(rev_reg_defs, rev_reg_def_ids)?;
let rev_status_lists = _rev_status_list(rev_status_list)?;
let map_nonrevoked_interval_override =
_nonrevoke_interval_override(nonrevoked_interval_override)?;

eprintln!("Loading presentation and pres_req objects...");
let presentation_binding = presentation.load()?;
let presentation_obj = presentation_binding.cast_ref()?;
let pres_req_binding = pres_req.load()?;
let pres_req_obj = pres_req_binding.cast_ref()?;

eprintln!("Calling verify_presentation...");
let verify = verify_presentation(
presentation.load()?.cast_ref()?,
pres_req.load()?.cast_ref()?,
presentation_obj,
pres_req_obj,
&schemas,
&cred_defs,
rev_reg_defs.as_ref(),
rev_status_lists,
Some(&map_nonrevoked_interval_override),
)?;

eprintln!("Verification result: {}", verify);
eprintln!("Setting result_p to: {}", i8::from(verify));
unsafe { *result_p = i8::from(verify) };
eprintln!("=== END RUST VERIFY PRESENTATION DEBUG ===");
Ok(())
})
}
Expand Down
59 changes: 59 additions & 0 deletions src/services/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,22 @@ pub fn verify_presentation(
&HashMap<RevocationRegistryDefinitionId, HashMap<u64, u64>>,
>,
) -> Result<bool> {
eprintln!("=== VERIFY_PRESENTATION FUNCTION START ===");
eprintln!("Schemas received ({} total):", schemas.len());
for (id, schema) in schemas {
eprintln!(" Schema ID: '{}', Name: '{}'", id, schema.name);
}
Copy link

Copilot AI Sep 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug print statements (eprintln!) should be removed from production code or replaced with proper logging using the trace! macro that's already available in this module.

Copilot uses AI. Check for mistakes.

eprintln!("CredDefs received ({} total):", cred_defs.len());
for (id, cred_def) in cred_defs {
eprintln!(" CredDef ID: '{}', Schema ID: '{}'", id, cred_def.schema_id);
}

eprintln!("Presentation identifiers:");
for (i, identifier) in presentation.identifiers.iter().enumerate() {
eprintln!(" [{}] Schema ID: '{}', CredDef ID: '{}'", i, identifier.schema_id, identifier.cred_def_id);
}

trace!("verify >>> presentation: {:?}, pres_req: {:?}, schemas: {:?}, cred_defs: {:?}, rev_reg_defs: {:?} rev_status_lists: {:?}",
presentation, pres_req, schemas, cred_defs, rev_reg_defs, rev_status_lists);

Expand All @@ -63,8 +79,19 @@ pub fn verify_presentation(
let received_predicates: HashMap<String, Identifier> = received_predicates(presentation)?;
let received_self_attested_attrs: HashSet<String> = received_self_attested_attrs(presentation);

eprintln!("Received revealed attrs: {} entries", received_revealed_attrs.len());
for (attr, identifier) in &received_revealed_attrs {
eprintln!(" '{}' -> Schema: '{}', CredDef: '{}'", attr, identifier.schema_id, identifier.cred_def_id);
}

eprintln!("Received predicates: {} entries", received_predicates.len());
for (pred, identifier) in &received_predicates {
eprintln!(" '{}' -> Schema: '{}', CredDef: '{}'", pred, identifier.schema_id, identifier.cred_def_id);
}

let pres_req = pres_req.value();

eprintln!("Starting attribute comparison...");
// Ensures that all attributes in the request is also in the presentation
compare_attr_from_proof_and_request(
pres_req,
Expand All @@ -73,10 +100,14 @@ pub fn verify_presentation(
&received_self_attested_attrs,
&received_predicates,
)?;
eprintln!("Attribute comparison passed");

eprintln!("Starting revealed attribute value verification...");
// Ensures the encoded values are same as request
verify_revealed_attribute_values(pres_req, presentation)?;
eprintln!("Revealed attribute values verified");

eprintln!("Starting restriction verification...");
// Ensures the restrictions set out in the request is met
verify_requested_restrictions(
pres_req,
Expand All @@ -88,27 +119,41 @@ pub fn verify_presentation(
&received_predicates,
&received_self_attested_attrs,
)?;
eprintln!("Restriction verification passed");

eprintln!("Creating CLProofVerifier...");
let mut proof_verifier = CLProofVerifier::new(
pres_req,
schemas,
cred_defs,
rev_reg_defs,
rev_status_lists.as_ref(),
)?;
eprintln!("CLProofVerifier created successfully");

eprintln!("Processing {} sub-proofs...", presentation.identifiers.len());
for (sub_proof_index, identifier) in presentation.identifiers.iter().enumerate() {
eprintln!("Processing sub-proof {} with identifier:", sub_proof_index);
eprintln!(" Schema ID: '{}'", identifier.schema_id);
eprintln!(" CredDef ID: '{}'", identifier.cred_def_id);
eprintln!(" RevReg ID: {:?}", identifier.rev_reg_id);
eprintln!(" Timestamp: {:?}", identifier.timestamp);

let attributes = presentation
.requested_proof
.get_attributes_for_credential(sub_proof_index as u32);
let predicates = presentation
.requested_proof
.get_predicates_for_credential(sub_proof_index as u32);

eprintln!(" Attributes for this credential: {} items", attributes.len());
eprintln!(" Predicates for this credential: {} items", predicates.len());

let (_, attrs_nonrevoked_interval) = pres_req.get_requested_attributes(&attributes)?;
let (_, pred_nonrevoked_interval) = pres_req.get_requested_predicates(&predicates)?;

{
eprintln!(" Checking non-revoked interval...");
check_non_revoked_interval(
proof_verifier.get_credential_definition(&identifier.cred_def_id)?,
attrs_nonrevoked_interval,
Expand All @@ -118,20 +163,34 @@ pub fn verify_presentation(
nonrevoke_interval_override,
identifier.timestamp,
)?;
eprintln!(" Non-revoked interval check passed");
}

eprintln!(" Adding sub-proof to verifier...");
proof_verifier.add_sub_proof(
&presentation.proof.proofs[sub_proof_index],
&identifier.schema_id,
&identifier.cred_def_id,
identifier.rev_reg_id.as_ref(),
identifier.timestamp,
)?;
eprintln!(" Sub-proof {} added successfully", sub_proof_index);
}

eprintln!("All sub-proofs processed. Starting final verification...");
eprintln!("About to call proof_verifier.verify() with {} sub-proofs", presentation.proof.proofs.len());
eprintln!("Pres_req nonce: {:?}", pres_req.nonce);
let valid = proof_verifier.verify(&presentation.proof)?;
eprintln!("Final verification result: {}", valid);

if !valid {
eprintln!("VERIFICATION FAILED - Debug info:");
eprintln!(" Proof proofs length: {}", presentation.proof.proofs.len());
eprintln!(" This indicates the cryptographic proof verification failed");
}

trace!("verify <<< valid: {:?}", valid);
eprintln!("=== VERIFY_PRESENTATION FUNCTION END ===");

Ok(valid)
}
Expand Down
Loading