#signature-verification #ring #verifier #alice #anonymous #group #lsag

ring_signature_verifier

A rust implementation of ring signatures generated by an Alice's Ring library

5 releases

0.1.4 Oct 7, 2024
0.1.3 Oct 7, 2024
0.1.2 Oct 7, 2024
0.1.1 Oct 7, 2024
0.1.0 Oct 7, 2024

#7 in #alice

MIT license

34KB
510 lines

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.

  2. LSAG (Linkable Spontaneous Anonymous Group Signature) Verification:
    The crate also provides LSAG signature verification. Refer to the LSAG Rust Verifier Documentation 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.

Getting Started

Add ring_signature_verifier to your project by including it in your Cargo.toml:

[dependencies]
ring_signature_verifier = "0.1.4"

Crate URL: crates.io/crates/ring_signature_verifier

Example Usage

Verifying an LSAG Signature from a Base64-Encoded String

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:

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

For more examples and detailed usage instructions, refer to the linked documentation or contact the maintainers contact@cypherlab.org.

Dependencies

~6.5–9MB
~157K SLoC