BLS12-381
  • 30 Jan 2024
  • 3 Minutes to read
  • Dark
    Light
  • PDF

BLS12-381

  • Dark
    Light
  • PDF

Article summary

BLS12-381 implemented in Scrypto is compliant with following standards:

It uses ciphersuite BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_ , which translates into:

  • Signature G2 variant (size 96 bytes)

  • Public key G1 variant (size 48 bytes)

  • Signature scheme POP (proof of possession)

Following methods are implemented within CryptoUtils module:

  • bls12381_v1_verify() - Verify a G2 signature of given message with given public key

  • bls12381_v1_aggregate_verify() - Verify an aggregated G2 signature using given vector of messages and public key tuples

  • bls12381_v1_fast_aggregate_verify() - Verify an aggregated G2 signature using a given message with given multiple keys

  • bls12381_g2_signature_aggregate() - Aggregate multiple G2 signatures into a single one

See the examples below:

use scrypto::prelude::*;

#[blueprint]
mod crypto_example {
    struct CryptoScrypto {}

    impl CryptoScrypto {
        pub fn bls12381_g1_public_key_conversions() {
            // Bls12381G1PublicKey might be converted from:
            // - hex string
            // - vector of bytes (48 bytes long)
            // Bls12381G1PublicKey might be converted to vector of bytes.
            let pub_key_str = "93b1aa7542a5423e21d8e84b4472c31664412cc604a666e9fdf03baf3c758e728c7a11576ebb01110ac39a0df95636e2";
            let pub_key = match Bls12381G1PublicKey::from_str(pub_key_str) {
                Ok(pub_key) => pub_key,
                Err(err) => panic!(
                    "Error getting Bls12381G1PublicKey from str, error: {:?}",
                    err
                ),
            };

            let pub_key_bytes = pub_key.to_vec(); // Convert to vector of bytes
                                                  //
            let _pub_key = match Bls12381G1PublicKey::try_from(pub_key_bytes.as_slice()) {
                Ok(pub_key) => pub_key,
                Err(err) => panic!(
                    "Error getting Bls12381G1PublicKey from bytes, error: {:?}",
                    err
                ),
            };
        }

        pub fn bls12381_g2_signature_conversions() {
            // Bls12381G2Signature might be converted from:
            // - from hex string
            // - from vector of bytes (96 bytes long)
            // Bls12381G2Signature might be converted to vector of bytes
            let signature_str = "82131f69b6699755f830e29d6ed41cbf759591a2ab598aa4e9686113341118d1db900d190436048601791121b5757c341045d4d0c94a95ec31a9ba6205f9b7504de85dadff52874375c58eec6cec28397279de87d5595101e398d31646d345bb";
            let signature = match Bls12381G2Signature::from_str(signature_str) {
                Ok(signature) => signature,
                Err(err) => panic!(
                    "Error getting Bls12381G2Signature from str, error: {:?}",
                    err
                ),
            };

            let signature_bytes = signature.to_vec(); // Convert to vector of bytes

            let _signature = match Bls12381G2Signature::try_from(signature_bytes.as_slice()) {
                Ok(signature) => signature,
                Err(err) => panic!(
                    "Error getting Bls12381G2Signature from bytes, error: {:?}",
                    err
                ),
            };
        }

        pub fn bls12381_v1_verify(
            message: Vec<u8>,
            pub_key: Bls12381G1PublicKey,
            signature: Bls12381G2Signature,
        ) -> bool {
            CryptoUtils::bls12381_v1_verify(message, pub_key, signature)
        }

        pub fn bls12381_v1_aggregate_verify(
            pub_keys_msgs: Vec<(Bls12381G1PublicKey, Vec<u8>)>,
            signature: Bls12381G2Signature,
        ) -> bool {
            // pub_keys_msgs is a vector of tuples of public keys and the corresponding messages
            CryptoUtils::bls12381_v1_aggregate_verify(pub_keys_msgs, signature)
        }

        pub fn bls12381_v1_fast_aggregate_verify(
            message: Vec<u8>,
            pub_keys: Vec<Bls12381G1PublicKey>,
            signature: Bls12381G2Signature,
        ) -> bool {
            CryptoUtils::bls12381_v1_fast_aggregate_verify(message, pub_keys, signature)
        }

        pub fn bls12381_g2_signature_aggregate(
            signatures: Vec<Bls12381G2Signature>,
        ) -> Bls12381G2Signature {
            CryptoUtils::bls12381_g2_signature_aggregate(signatures)
        }
    }
}


Was this article helpful?

What's Next