BLS12-381

BLS12-381 is a bit of a special curve. It is a pairing-friendly curve, allowing for fun things such as aggregated signatures. At the moment, CosmWasm only supports signature verifications. In the future we might add support for zero-knowledge proofs on this curve.

Common examples where this curve is used are Ethereum block-headers and drand (opens in a new tab) randomness beacons.

Example

CosmWasm offers a byte-oriented API for signature verification. This API also doesn't care whether the public key is part of the G1 or G2 group (same for the other components). They just have to somehow fit together.

Verify on G1

Signature verification with public key in G1:

contract.rs
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(
    deps: Deps,
    _env: Env,
    msg: Bls12VerifyMsg,
) -> StdResult<QueryResponse> {
    // Verify the signature. On chain!
    let msg_hash = deps.api.bls12_381_hash_to_g2(HashFunction::Sha256, &msg.msg, &msg.dst)?;
    let is_valid = deps.api.bls12_381_pairing_equality(&BLS12_381_G1_GENERATOR, &msg.signature, &msg.pubkey, &msg_hash)?;
    let response = to_json_binary(&VerifyResponse {
        is_valid
    })?;
 
    Ok(response)
}

Verify on G2

Signature verification with public key in G2 (See https://hackmd.io/@benjaminion/bls12-381#Verification (opens in a new tab) in combination with https://hackmd.io/@benjaminion/bls12-381#Swapping-G1-and-G2 (opens in a new tab)):

contract.rs
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(
    deps: Deps,
    _env: Env,
    msg: Bls12VerifyMsg,
) -> StdResult<QueryResponse> {
    // Verify the signature. On chain!
    let msg_hash = deps.api.bls12_381_hash_to_g1(HashFunction::Sha256, &msg.msg, &msg.dst)?;
    let is_valid = deps.api.bls12_381_pairing_equality(&msg.signature, &BLS12_381_G2_GENERATOR, &msg_hash, &msg.pubkey)?;
    let response = to_json_binary(&VerifyResponse {
        is_valid
    })?;
 
    Ok(response)
}