Skip to content

Latest commit

 

History

History
448 lines (236 loc) · 13.5 KB

Authenticator.md

File metadata and controls

448 lines (236 loc) · 13.5 KB

Module 0x1::Authenticator

Move representation of the authenticator types

Struct MultiEd25519PublicKey

A multi-ed25519 public key

struct MultiEd25519PublicKey has copy, drop, store
Fields
public_keys: vector<vector<u8>>
vector of ed25519 public keys
threshold: u8
approval threshold

Constants

const AUTHENTICATION_KEY_LENGTH: u64 = 32;

const ED25519_SCHEME_ID: u8 = 0;

Not enough keys were provided for the specified threshold when creating an MultiEd25519 key

Too many keys were provided for the specified threshold when creating an MultiEd25519 key

Threshold provided was 0 which can't be used to create a MultiEd25519 key

const EZERO_THRESHOLD: u64 = 102;

Maximum number of keys allowed in a MultiEd25519 public/private key

const MAX_MULTI_ED25519_KEYS: u64 = 32;

const MULTI_ED25519_SCHEME_ID: u8 = 1;

Function create_multi_ed25519

Create a a multisig policy from a vector of ed25519 public keys and a threshold. Note: this does not check uniqueness of keys. Repeated keys are convenient to encode weighted multisig policies. For example Alice AND 1 of Bob or Carol is public_key: {alice_key, alice_key, bob_key, carol_key}, threshold: 3 Aborts if threshold is zero or bigger than the length of public_keys.

public fun create_multi_ed25519(public_keys: vector<vector<u8>>, threshold: u8): Authenticator::MultiEd25519PublicKey
Implementation
public fun create_multi_ed25519(
    public_keys: vector<vector<u8>>,
    threshold: u8
): MultiEd25519PublicKey {
    // check threshold requirements
    let len = Vector::length(&public_keys);
    assert!(threshold != 0, Errors::invalid_argument(EZERO_THRESHOLD));
    assert!(
        (threshold as u64) <= len,
        Errors::invalid_argument(ENOT_ENOUGH_KEYS_FOR_THRESHOLD)
    );
    // the multied25519 signature scheme allows at most 32 keys
    assert!(
        len <= MAX_MULTI_ED25519_KEYS,
        Errors::invalid_argument(ENUM_KEYS_ABOVE_MAX_THRESHOLD)
    );

    MultiEd25519PublicKey { public_keys, threshold }
}
Specification
aborts_if threshold == 0;
aborts_if threshold > Vector::length(public_keys);
aborts_if Vector::length(public_keys) > 32;

Function ed25519_authentication_key

Compute an authentication key for the ed25519 public key public_key

public fun ed25519_authentication_key(public_key: vector<u8>): vector<u8>
Implementation
public fun ed25519_authentication_key(public_key: vector<u8>): vector<u8> {
    Vector::push_back(&mut public_key, ED25519_SCHEME_ID);
    Hash::sha3_256(public_key)
}
Specification
pragma opaque = true;
aborts_if false;
ensures [abstract] result == spec_ed25519_authentication_key(public_key);

We use an uninterpreted function to represent the result of key construction. The actual value does not matter for the verification of callers.

fun spec_ed25519_authentication_key(public_key: vector<u8>): vector<u8>;

Function derived_address

convert authentication key to address

public fun derived_address(authentication_key: vector<u8>): address
Implementation
public fun derived_address(authentication_key: vector<u8>): address {
    assert!(Vector::length(&authentication_key) == AUTHENTICATION_KEY_LENGTH, Errors::invalid_argument(EWRONG_AUTHENTICATION_KEY_LENGTH));
    let address_bytes = Vector::empty<u8>();

    let i = 16;
    while (i < 32) {
        let b = *Vector::borrow(&authentication_key, i);
        Vector::push_back(&mut address_bytes, b);
        i = i + 1;
    };

    BCS::to_address(address_bytes)
}
Specification
pragma opaque = true;
aborts_if len(authentication_key) != 32;
ensures [abstract] result == spec_derived_address(authentication_key);

We use an uninterpreted function to represent the result of derived address. The actual value does not matter for the verification of callers.

fun spec_derived_address(authentication_key: vector<u8>): address;

Function multi_ed25519_authentication_key

Compute a multied25519 account authentication key for the policy k

Implementation
public fun multi_ed25519_authentication_key(k: &MultiEd25519PublicKey): vector<u8> {
    let public_keys = &k.public_keys;
    let len = Vector::length(public_keys);
    let authentication_key_preimage = Vector::empty();
    let i = 0;
    while (i < len) {
        let public_key = *Vector::borrow(public_keys, i);
        Vector::append(
            &mut authentication_key_preimage,
            public_key
        );
        i = i + 1;
    };
    Vector::append(&mut authentication_key_preimage, BCS::to_bytes(&k.threshold));
    Vector::push_back(&mut authentication_key_preimage, MULTI_ED25519_SCHEME_ID);
    Hash::sha3_256(authentication_key_preimage)
}
Specification
aborts_if false;

Function public_keys

Return the public keys involved in the multisig policy k

public fun public_keys(k: &Authenticator::MultiEd25519PublicKey): &vector<vector<u8>>
Implementation
public fun public_keys(k: &MultiEd25519PublicKey): &vector<vector<u8>> {
    &k.public_keys
}
Specification
aborts_if false;

Function threshold

Return the threshold for the multisig policy k

Implementation
public fun threshold(k: &MultiEd25519PublicKey): u8 {
    *&k.threshold
}
Specification
aborts_if false;

Module Specification

pragma verify;
pragma aborts_if_is_strict;