starcoin-framework

Module 0x1::Authenticator

Move representation of the authenticator types

use 0x1::BCS;
use 0x1::Errors;
use 0x1::Hash;
use 0x1::Vector;

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

const ENOT_ENOUGH_KEYS_FOR_THRESHOLD: u64 = 103;

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

const ENUM_KEYS_ABOVE_MAX_THRESHOLD: u64 = 104;

const EWRONG_AUTHENTICATION_KEY_LENGTH: u64 = 101;

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

public fun multi_ed25519_authentication_key(k: &Authenticator::MultiEd25519PublicKey): vector<u8>
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

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

Module Specification

pragma verify;
pragma aborts_if_is_strict;