axelar-cgp-sui

Module axelar_gateway::proof

use axelar_gateway::bytes32;
use axelar_gateway::weighted_signer;
use axelar_gateway::weighted_signers;
use std::ascii;
use std::bcs;
use std::option;
use std::string;
use std::vector;
use sui::address;
use sui::bcs;
use sui::ecdsa_k1;
use sui::hash;
use sui::hex;

Struct Signature

public struct Signature has copy, drop, store
Fields
bytes: vector<u8>

Struct Proof

public struct Proof has copy, drop, store
Fields
signers: axelar_gateway::weighted_signers::WeightedSigners
signatures: vector<axelar_gateway::proof::Signature>

Constants

Length of the signature

const SIGNATURE_LENGTH: u64 = 65;

Invalid length of the bytes

#[error]
const EInvalidSignatureLength: vector<u8> = b"invalid signature length: expected 65 bytes";

#[error]
const ELowSignaturesWeight: vector<u8> = b"insufficient signatures weight";

#[error]
const ESignerNotFound: vector<u8> = b"no signer found with the specified public key in the given range";

#[error]
const ERedundantSignaturesProvided: vector<u8> = b"redundant signatures provided";

Function signers

The signers of the proof

public(package) fun signers(proof: &axelar_gateway::proof::Proof): &axelar_gateway::weighted_signers::WeightedSigners
Implementation
public(package) fun signers(proof: &Proof): &WeightedSigners {
    &proof.signers
}

Function signatures

The proof signatures

public(package) fun signatures(proof: &axelar_gateway::proof::Proof): &vector<axelar_gateway::proof::Signature>
Implementation
public(package) fun signatures(proof: &Proof): &vector<Signature> {
    &proof.signatures
}

Function new_signature

public(package) fun new_signature(bytes: vector<u8>): axelar_gateway::proof::Signature
Implementation
public(package) fun new_signature(bytes: vector<u8>): Signature {
    assert!(bytes.length() == SIGNATURE_LENGTH, EInvalidSignatureLength);
    Signature {
        bytes: bytes,
    }
}

Function recover_pub_key

Recover the public key from an EVM recoverable signature, using keccak256 as the hash function

public(package) fun recover_pub_key(self: &axelar_gateway::proof::Signature, message: &vector<u8>): vector<u8>
Implementation
public(package) fun recover_pub_key(self: &Signature, message: &vector<u8>): vector<u8> {
    ecdsa::secp256k1_ecrecover(&self.bytes, message, 0)
}

Function validate

Validates the signatures of a message against the signers. The total weight of the signatures must be greater than or equal to the threshold. Otherwise, the error ELowSignaturesWeight is raised.

public(package) fun validate(self: &axelar_gateway::proof::Proof, message: vector<u8>)
Implementation
public(package) fun validate(self: &Proof, message: vector<u8>) {
    let signers = &self.signers;
    let signatures = &self.signatures;
    assert!(signatures.length() != 0, ELowSignaturesWeight);
    let threshold = signers.threshold();
    let signatures_length = signatures.length();
    let mut total_weight: u128 = 0;
    let mut signer_index = 0;
    let mut i = 0;
    while (i < signatures_length) {
        let pub_key = signatures[i].recover_pub_key(&message);
        let (weight, index) = find_weight_by_pub_key_from(
            signers,
            signer_index,
            &pub_key,
        );
        total_weight = total_weight + weight;
        if (total_weight >= threshold) {
            if (i + 1 == signatures_length) {
                return
            };
            abort ERedundantSignaturesProvided
        };
        i = i + 1;
        signer_index = index + 1;
    };
    abort ELowSignaturesWeight
}

Function find_weight_by_pub_key_from

Finds the weight of a signer in the weighted signers by its public key.

fun find_weight_by_pub_key_from(signers: &axelar_gateway::weighted_signers::WeightedSigners, signer_index: u64, pub_key: &vector<u8>): (u128, u64)
Implementation
fun find_weight_by_pub_key_from(signers: &WeightedSigners, signer_index: u64, pub_key: &vector<u8>): (u128, u64) {
    let signers = signers.signers();
    let length = signers.length();
    let mut index = signer_index;
    // Find the first signer that satisfies the predicate
    while (index < length && signers[index].pub_key() != pub_key) {
        index = index + 1;
    };
    // If no signer satisfies the predicate, return an error
    assert!(index < length, ESignerNotFound);
    (signers[index].weight(), index)
}

Function peel_signature

public(package) fun peel_signature(bcs: &mut sui::bcs::BCS): axelar_gateway::proof::Signature
Implementation
public(package) fun peel_signature(bcs: &mut BCS): Signature {
    let bytes = bcs.peel_vec_u8();
    new_signature(bytes)
}

Function peel

public(package) fun peel(bcs: &mut sui::bcs::BCS): axelar_gateway::proof::Proof
Implementation
public(package) fun peel(bcs: &mut BCS): Proof {
    let signers = weighted_signers::peel(bcs);
    let length = bcs.peel_vec_length();
    Proof {
        signers,
        signatures: vector::tabulate!(length, |_| peel_signature(bcs)),
    }
}