# Alice's Ring: `ring_signature_verifier` An implementation of the SAG and LSAG verifiers written in Rust, designed to verify ring signatures generated by the Alice's Ring library. This crate provides functionalities to verify both Spontaneous Anonymous Group (SAG) and Linkable Spontaneous Anonymous Group (LSAG) signatures. ## Overview The Rust crate offers two primary verification schemes: 1. **SAG (Spontaneous Anonymous Group Signatures) Verification:** This crate enables verification of SAG signatures. More details on how SAG verification works can be found in the [SAG Rust Verifier Documentation](https://docs.alicesring.org/docs/SAG/SAG-rust-verifier). 2. **LSAG (Linkable Spontaneous Anonymous Group Signature) Verification:** The crate also provides LSAG signature verification. Refer to the [LSAG Rust Verifier Documentation](https://docs.alicesring.org/docs/LSAG/LSAG-rust-verifier) for more details. > **Note:** The verifier is designed to work with ring signatures generated by Alice's Ring library and might not be compatible with other ring signature implementations. For a detailed comparison of SAG and LSAG schemes, see the [differences between SAG and LSAG](https://docs.alicesring.org/docs/ring-signatures). ## Getting Started Add `ring_signature_verifier` to your project by including it in your `Cargo.toml`: ```toml [dependencies] ring_signature_verifier = "0.1.4" ``` > Crate URL: [crates.io/crates/ring_signature_verifier](https://crates.io/crates/ring_signature_verifier) ### Example Usage #### Verifying an LSAG Signature from a Base64-Encoded String ```rust use ring_signature_verifier::lsag_verifier::verify_b64_lsag; fn main() { // Base64-encoded LSAG signature let b64_sig = "eyJtZXNzYWdlIjoibWVzc2FnZSIsInJpbmciOlsiMDIwOGY0ZjM3ZTJkOGY3NGUxOGMxYjhmZGUyMzc0ZDVmMjg0MDJmYjhhYjdmZDFjYzViNzg2YWE0MDg1MWE3MGNiIiwiMDMxNmQ3ZGE3MGJhMjQ3YTZhNDBiYjMxMDE4N2U4Nzg5YjgwYzQ1ZmE2ZGMwMDYxYWJiOGNlZDQ5Y2JlN2Y4ODdmIiwiMDIyMTg2OWNhM2FlMzNiZTNhNzMyN2U5YTAyNzIyMDNhZmE3MmM1MmE1NDYwY2ViOWY0YTUwOTMwNTMxYmQ5MjZhIiwiMDIzMzdkNmY1NzdlNjZhMjFhNzgzMWMwODdjNjgzNmExYmFlMzcwODZiZjQzMTQwMDgxMWFjN2M2ZTk2YzhjY2JiIl0sImMiOiI4NjM3OWI0Mzg2MWU5NTBiNWZhNGI3NTcxYWZmMGM2MDA0NTc4ZTcxMjgwYWFlZGI5OTM4MzNjOWJkZTYzYzQzIiwicmVzcG9uc2VzIjpbImQ2YzE4NTRlZWIxMzJkNTg4NmFjNTkwYzUzMGE1NWE3ZmJhM2Q5MmM0ZWI2ODk2YTcyOGIwYTYxODk5YWQ5MDIiLCI2YTUxZDczMWIzOTgwMzZlZDNiM2I1Y2ZkMjA2NDA3YTM1ZmQxMWZhYTJiYmFkMTY1OGJjZjlmMDhiOWM1ZmI4IiwiNmE1MWQ3MzFiMzk4MDM2ZWQzYjNiNWNmZDIwNjQwN2EzNWZkMTFmYWEyYmJhZDE2NThiY2Y5ZjA4YjljNWZiOCIsIjZhNTFkNzMxYjM5ODAzNmVkM2IzYjVjZmQyMDY0MDdhMzVmZDExZmFhMmJiYWQxNjU4YmNmOWYwOGI5YzVmYjgiXSwiY3VydmUiOiJ7XCJjdXJ2ZVwiOlwiU0VDUDI1NksxXCJ9Iiwia2V5SW1hZ2UiOiIwMjE5MWViOWYwNjM2YTViMWE4N2VkNjZjYzAwZDViM2ZmYTM1ZDRlMDRjNGIyMWM4ZTQ4ZGI5ODdhYmI2MDBiMTEiLCJsaW5rYWJpbGl0eUZsYWciOiJsaW5rYWJpbGl0eSBmbGFnIiwiZXZtV2l0bmVzc2VzIjpbXX0=".to_string(); // Is signature valid? true println!("Is signature valid? {:?}", verify_b64_lsag(b64_sig)); } ``` #### Verifying an LSAG Signature Using Public Key Points Here’s a more detailed example of how to verify an LSAG signature using public key points, responses, and key image: ```rust use ring_signature_verifier::{ lsag_verifier::{verify_lsag, Lsag}, elliptic_curve::sec1::FromEncodedPoint, utils::{scalar_from_hex::scalar_from_hex, test_utils::get_ring}, }; use ring_signature_verifier::k256::{self, AffinePoint, EncodedPoint}; fn main() { let message = "message".to_string(); let points = [ ( "4051293998585674784991639592782214972820158391371785981004352359465450369227", "88166831356626186178414913298033275054086243781277878360288998796587140930350", ), ( "10332262407579932743619774205115914274069865521774281655691935407979316086911", "100548694955223641708987702795059132275163693243234524297947705729826773642827", ), ( "15164162595175125008547705889856181828932143716710538299042410382956573856362", "20165396248642806335661137158563863822683438728408180285542980607824890485122", ), ( "23289579613515307249488379845935313471996837170244623503719929765426073488571", "51508290999221377635014061085578700551081950582306096405012518980034910355762", ), ]; let ring = get_ring(&points); let x = scalar_from_hex("191eb9f0636a5b1a87ed66cc00d5b3ffa35d4e04c4b21c8e48db987abb600b11"); let y = scalar_from_hex("2cdf899ff765f26abb272b8228ccc4b1f69192e614d9c0d44a52b78bb9af8774"); let key_image = AffinePoint::from_encoded_point(&EncodedPoint::from_affine_coordinates( &x.unwrap().into(), &y.unwrap().into(), false, )).unwrap(); let c0: k256::Scalar = scalar_from_hex("86379b43861e950b5fa4b7571aff0c6004578e71280aaedb993833c9bde63c43") .unwrap(); let responses = vec![ scalar_from_hex("d6c1854eeb132d5886ac590c530a55a7fba3d92c4eb6896a728b0a61899ad902").unwrap(), scalar_from_hex("6a51d731b398036ed3b3b5cfd206407a35fd11faa2bbad1658bcf9f08b9c5fb8").unwrap(), scalar_from_hex("6a51d731b398036ed3b3b5cfd206407a35fd11faa2bbad1658bcf9f08b9c5fb8").unwrap(), scalar_from_hex("6a51d731b398036ed3b3b5cfd206407a35fd11faa2bbad1658bcf9f08b9c5fb8").unwrap(), ]; let linkability_flag = Some("linkability flag".to_string()); let lsag_signature = Lsag { ring, message, c0, responses, key_image, linkability_flag, }; let result = verify_lsag(lsag_signature); // should display true println!("Is LSAG valid ? {:?}", result); } ``` ## Additional Resources - [SAG Rust Verifier Documentation](https://docs.alicesring.org/docs/SAG/SAG-rust-verifier) - [LSAG Rust Verifier Documentation](https://docs.alicesring.org/docs/LSAG/LSAG-rust-verifier) - [LSAG EVM Verifier Documentation](https://docs.alicesring.org/docs/LSAG/LSAG-evm-verifier) For more examples and detailed usage instructions, refer to the linked documentation or contact the maintainers [contact@cypherlab.org](mailto:contact@cypherlab.org).