axelar-cgp-sui

Module 0xa1::proof

use 0x2::bcs;
use 0x2::ecdsa_k1;
use 0xa1::weighted_signer;
use 0xa1::weighted_signers;

Struct Signature

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

Struct Proof

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

Constants

Invalid length of the bytes

const EInvalidSignatureLength: vector<u8> = [105, 110, 118, 97, 108, 105, 100, 32, 115, 105, 103, 110, 97, 116, 117, 114, 101, 32, 108, 101, 110, 103, 116, 104, 58, 32, 101, 120, 112, 101, 99, 116, 101, 100, 32, 54, 53, 32, 98, 121, 116, 101, 115];

const ELowSignaturesWeight: vector<u8> = [105, 110, 115, 117, 102, 102, 105, 99, 105, 101, 110, 116, 32, 115, 105, 103, 110, 97, 116, 117, 114, 101, 115, 32, 119, 101, 105, 103, 104, 116];

const ERedundantSignaturesProvided: vector<u8> = [114, 101, 100, 117, 110, 100, 97, 110, 116, 32, 115, 105, 103, 110, 97, 116, 117, 114, 101, 115, 32, 112, 114, 111, 118, 105, 100, 101, 100];

const ESignerNotFound: vector<u8> = [110, 111, 32, 115, 105, 103, 110, 101, 114, 32, 102, 111, 117, 110, 100, 32, 119, 105, 116, 104, 32, 116, 104, 101, 32, 115, 112, 101, 99, 105, 102, 105, 101, 100, 32, 112, 117, 98, 108, 105, 99, 32, 107, 101, 121, 32, 105, 110, 32, 116, 104, 101, 32, 103, 105, 118, 101, 110, 32, 114, 97, 110, 103, 101];

Length of the signature

const SIGNATURE_LENGTH: u64 = 65;

Function signers

The signers of the proof

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

Function signatures

The proof signatures

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

Function new_signature

public(friend) fun new_signature(bytes: vector<u8>): 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(friend) fun recover_pub_key(self: &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(friend) fun validate(self: &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: &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(friend) fun peel_signature(bcs: &mut bcs::BCS): proof::Signature
Implementation
public(package) fun peel_signature(bcs: &mut BCS): Signature {
    let bytes = bcs.peel_vec_u8();

    new_signature(bytes)
}

Function peel

public(friend) fun peel(bcs: &mut bcs::BCS): 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)),
    }
}