0xa1::proof
Signature
Proof
signers
signatures
new_signature
recover_pub_key
validate
find_weight_by_pub_key_from
peel_signature
peel
use 0x2::bcs;
use 0x2::ecdsa_k1;
use 0xa1::weighted_signer;
use 0xa1::weighted_signers;
Signature
struct Signature has copy, drop, store
bytes: vector<u8>
Proof
struct Proof has copy, drop, store
signers: weighted_signers::WeightedSigners
signatures: vector<proof::Signature>
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 ERedundantSignaturesProvided: vector<u8> = b"redundant signatures provided";
#[error]
const ESignerNotFound: vector<u8> = b"no signer found with the specified public key in the given range";
Length of the signature
const SIGNATURE_LENGTH: u64 = 65;
signers
The signers of the proof
public(friend) fun signers(proof: &proof::Proof): &weighted_signers::WeightedSigners
signatures
The proof signatures
public(friend) fun signatures(proof: &proof::Proof): &vector<proof::Signature>
public(package) fun signatures(proof: &Proof): &vector<Signature> {
&proof.signatures
}
new_signature
public(friend) fun new_signature(bytes: vector<u8>): proof::Signature
public(package) fun new_signature(bytes: vector<u8>): Signature {
assert!(bytes.length() == SIGNATURE_LENGTH, EInvalidSignatureLength);
Signature {
bytes: bytes,
}
}
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>
public(package) fun recover_pub_key(
self: &Signature,
message: &vector<u8>,
): vector<u8> {
ecdsa::secp256k1_ecrecover(&self.bytes, message, 0)
}
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>)
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
}
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)
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)
}
peel_signature
public(friend) fun peel_signature(bcs: &mut bcs::BCS): proof::Signature
public(package) fun peel_signature(bcs: &mut BCS): Signature {
let bytes = bcs.peel_vec_u8();
new_signature(bytes)
}
peel
public(friend) fun peel(bcs: &mut bcs::BCS): proof::Proof
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)),
}
}