ed25519 - [mainnet]
Contains functions for:
- Ed25519 digital signatures: i.e., EdDSA signatures over Edwards25519 curves with co-factor 8
use 0x1::bcs;use 0x1::error;use 0x1::hash;use 0x1::option;use 0x1::type_info;
Constants
The size of a serialized public key, in bytes.
const PUBLIC_KEY_NUM_BYTES: u64 = 32;
Wrong number of bytes were given as input when deserializing an Ed25519 public key.
const E_WRONG_PUBKEY_SIZE: u64 = 1;
Wrong number of bytes were given as input when deserializing an Ed25519 signature.
const E_WRONG_SIGNATURE_SIZE: u64 = 2;
The size of a serialized signature, in bytes.
const SIGNATURE_NUM_BYTES: u64 = 64;
The identifier of the Ed25519 signature scheme, which is used when deriving Aptos authentication keys by hashing it together with an Ed25519 public key.
const SIGNATURE_SCHEME_ID: u8 = 0;
Structs
SignedMessage
A BCS-serializable message, which one can verify signatures on via signature_verify_strict_t
struct SignedMessage<MessageType> has drop
Fields
-
type_info: type_info::TypeInfo
-
inner: MessageType
UnvalidatedPublicKey
An unvalidated Ed25519 public key: not necessarily an elliptic curve point, just a sequence of 32 bytes
struct UnvalidatedPublicKey has copy, drop, store
Fields
-
bytes: vector<u8>
ValidatedPublicKey
A validated Ed25519 public key: not necessarily a prime-order point, could be mixed-order, but will never be a small-order point.
For now, this struct is not used in any verification functions, but it might be in the future.
struct ValidatedPublicKey has copy, drop, store
Fields
-
bytes: vector<u8>
Signature
A purported Ed25519 signature that can be verified via signature_verify_strict
or signature_verify_strict_t
.
struct Signature has copy, drop, store
Fields
-
bytes: vector<u8>
Functions
new_unvalidated_public_key_from_bytes
Parses the input 32 bytes as an unvalidated Ed25519 public key.
public fun new_unvalidated_public_key_from_bytes(bytes: vector<u8>): ed25519::UnvalidatedPublicKey
Implementation
public fun new_unvalidated_public_key_from_bytes(bytes: vector<u8>): UnvalidatedPublicKey { assert!(bytes.length() == PUBLIC_KEY_NUM_BYTES, std::error::invalid_argument(E_WRONG_PUBKEY_SIZE)); UnvalidatedPublicKey { bytes }}
new_validated_public_key_from_bytes
Parses the input 32 bytes as a validated Ed25519 public key.
public fun new_validated_public_key_from_bytes(bytes: vector<u8>): option::Option<ed25519::ValidatedPublicKey>
Implementation
public fun new_validated_public_key_from_bytes(bytes: vector<u8>): Option<ValidatedPublicKey> { if (public_key_validate_internal(bytes)) { option::some(ValidatedPublicKey { bytes }) } else { option::none<ValidatedPublicKey>() }}
new_signature_from_bytes
Parses the input 64 bytes as a purported Ed25519 signature.
public fun new_signature_from_bytes(bytes: vector<u8>): ed25519::Signature
Implementation
public fun new_signature_from_bytes(bytes: vector<u8>): Signature { assert!(bytes.length() == SIGNATURE_NUM_BYTES, std::error::invalid_argument(E_WRONG_SIGNATURE_SIZE)); Signature { bytes }}
public_key_to_unvalidated
Converts a ValidatedPublicKey to an UnvalidatedPublicKey, which can be used in the strict verification APIs.
public fun public_key_to_unvalidated(pk: &ed25519::ValidatedPublicKey): ed25519::UnvalidatedPublicKey
Implementation
public fun public_key_to_unvalidated(pk: &ValidatedPublicKey): UnvalidatedPublicKey { UnvalidatedPublicKey { bytes: pk.bytes }}
public_key_into_unvalidated
Moves a ValidatedPublicKey into an UnvalidatedPublicKey, which can be used in the strict verification APIs.
public fun public_key_into_unvalidated(pk: ed25519::ValidatedPublicKey): ed25519::UnvalidatedPublicKey
Implementation
public fun public_key_into_unvalidated(pk: ValidatedPublicKey): UnvalidatedPublicKey { UnvalidatedPublicKey { bytes: pk.bytes }}
unvalidated_public_key_to_bytes
Serializes an UnvalidatedPublicKey struct to 32-bytes.
public fun unvalidated_public_key_to_bytes(pk: &ed25519::UnvalidatedPublicKey): vector<u8>
Implementation
public fun unvalidated_public_key_to_bytes(pk: &UnvalidatedPublicKey): vector<u8> { pk.bytes}
validated_public_key_to_bytes
Serializes an ValidatedPublicKey struct to 32-bytes.
public fun validated_public_key_to_bytes(pk: &ed25519::ValidatedPublicKey): vector<u8>
Implementation
public fun validated_public_key_to_bytes(pk: &ValidatedPublicKey): vector<u8> { pk.bytes}
signature_to_bytes
Serializes a Signature struct to 64-bytes.
public fun signature_to_bytes(sig: &ed25519::Signature): vector<u8>
Implementation
public fun signature_to_bytes(sig: &Signature): vector<u8> { sig.bytes}
public_key_validate
Takes in an unvalidated public key and attempts to validate it.
Returns Some(ValidatedPublicKey)
if successful and None
otherwise.
public fun public_key_validate(pk: &ed25519::UnvalidatedPublicKey): option::Option<ed25519::ValidatedPublicKey>
Implementation
public fun public_key_validate(pk: &UnvalidatedPublicKey): Option<ValidatedPublicKey> { new_validated_public_key_from_bytes(pk.bytes)}
signature_verify_strict
Verifies a purported Ed25519 signature
under an unvalidated public_key
on the specified message
.
This call will validate the public key by checking it is NOT in the small subgroup.
public fun signature_verify_strict(signature: &ed25519::Signature, public_key: &ed25519::UnvalidatedPublicKey, message: vector<u8>): bool
Implementation
public fun signature_verify_strict( signature: &Signature, public_key: &UnvalidatedPublicKey, message: vector<u8>): bool { signature_verify_strict_internal(signature.bytes, public_key.bytes, message)}
signature_verify_strict_t
This function is used to verify a signature on any BCS-serializable type T. For now, it is used to verify the proof of private key ownership when rotating authentication keys.
public fun signature_verify_strict_t<T: drop>(signature: &ed25519::Signature, public_key: &ed25519::UnvalidatedPublicKey, data: T): bool
Implementation
public fun signature_verify_strict_t<T: drop>(signature: &Signature, public_key: &UnvalidatedPublicKey, data: T): bool { let encoded = SignedMessage { type_info: type_info::type_of<T>(), inner: data, };
signature_verify_strict_internal(signature.bytes, public_key.bytes, bcs::to_bytes(&encoded))}
new_signed_message
Helper method to construct a SignedMessage struct.
public fun new_signed_message<T: drop>(data: T): ed25519::SignedMessage<T>
Implementation
public fun new_signed_message<T: drop>(data: T): SignedMessage<T> { SignedMessage { type_info: type_info::type_of<T>(), inner: data, }}
unvalidated_public_key_to_authentication_key
Derives the Aptos-specific authentication key of the given Ed25519 public key.
public fun unvalidated_public_key_to_authentication_key(pk: &ed25519::UnvalidatedPublicKey): vector<u8>
Implementation
public fun unvalidated_public_key_to_authentication_key(pk: &UnvalidatedPublicKey): vector<u8> { public_key_bytes_to_authentication_key(pk.bytes)}
validated_public_key_to_authentication_key
Derives the Aptos-specific authentication key of the given Ed25519 public key.
public fun validated_public_key_to_authentication_key(pk: &ed25519::ValidatedPublicKey): vector<u8>
Implementation
public fun validated_public_key_to_authentication_key(pk: &ValidatedPublicKey): vector<u8> { public_key_bytes_to_authentication_key(pk.bytes)}
public_key_bytes_to_authentication_key
Derives the Aptos-specific authentication key of the given Ed25519 public key.
fun public_key_bytes_to_authentication_key(pk_bytes: vector<u8>): vector<u8>
Implementation
fun public_key_bytes_to_authentication_key(pk_bytes: vector<u8>): vector<u8> { pk_bytes.push_back(SIGNATURE_SCHEME_ID); std::hash::sha3_256(pk_bytes)}
public_key_validate_internal
Return true
if the bytes in public_key
can be parsed as a valid Ed25519 public key: i.e., it passes
points-on-curve and not-in-small-subgroup checks.
Returns false
otherwise.
fun public_key_validate_internal(bytes: vector<u8>): bool
Implementation
native fun public_key_validate_internal(bytes: vector<u8>): bool;
signature_verify_strict_internal
Return true if the Ed25519 signature
on message
verifies against the Ed25519 public_key
.
Returns false
if either:
signature
orpublic key
are of wrong sizespublic_key
does not pass points-on-curve or not-in-small-subgroup checks,signature
does not pass points-on-curve or not-in-small-subgroup checks,- the signature on
message
does not verify.
fun signature_verify_strict_internal(signature: vector<u8>, public_key: vector<u8>, message: vector<u8>): bool
Implementation
native fun signature_verify_strict_internal( signature: vector<u8>, public_key: vector<u8>, message: vector<u8>): bool;
Specification
new_unvalidated_public_key_from_bytes
public fun new_unvalidated_public_key_from_bytes(bytes: vector<u8>): ed25519::UnvalidatedPublicKey
include NewUnvalidatedPublicKeyFromBytesAbortsIf;ensures result == UnvalidatedPublicKey { bytes };
schema NewUnvalidatedPublicKeyFromBytesAbortsIf { bytes: vector<u8>; aborts_if len(bytes) != PUBLIC_KEY_NUM_BYTES;}
new_validated_public_key_from_bytes
public fun new_validated_public_key_from_bytes(bytes: vector<u8>): option::Option<ed25519::ValidatedPublicKey>
aborts_if false;let cond = spec_public_key_validate_internal(bytes);ensures cond ==> result == option::spec_some(ValidatedPublicKey{bytes});ensures !cond ==> result == option::spec_none<ValidatedPublicKey>();
new_signature_from_bytes
public fun new_signature_from_bytes(bytes: vector<u8>): ed25519::Signature
include NewSignatureFromBytesAbortsIf;ensures result == Signature { bytes };
schema NewSignatureFromBytesAbortsIf { bytes: vector<u8>; aborts_if len(bytes) != SIGNATURE_NUM_BYTES;}
public_key_bytes_to_authentication_key
fun public_key_bytes_to_authentication_key(pk_bytes: vector<u8>): vector<u8>
pragma opaque;aborts_if false;ensures [abstract] result == spec_public_key_bytes_to_authentication_key(pk_bytes);
public_key_validate_internal
fun public_key_validate_internal(bytes: vector<u8>): bool
pragma opaque;aborts_if false;ensures result == spec_public_key_validate_internal(bytes);
signature_verify_strict_internal
fun signature_verify_strict_internal(signature: vector<u8>, public_key: vector<u8>, message: vector<u8>): bool
pragma opaque;aborts_if false;ensures result == spec_signature_verify_strict_internal(signature, public_key, message);
Helper functions
fun spec_signature_verify_strict_internal( signature: vector<u8>, public_key: vector<u8>, message: vector<u8>): bool;
fun spec_public_key_validate_internal(bytes: vector<u8>): bool;
fun spec_public_key_bytes_to_authentication_key(pk_bytes: vector<u8>): vector<u8>;
fun spec_signature_verify_strict_t<T>(signature: Signature, public_key: UnvalidatedPublicKey, data: T): bool { let encoded = SignedMessage<T> { type_info: type_info::type_of<T>(), inner: data, }; let message = bcs::serialize(encoded); spec_signature_verify_strict_internal(signature.bytes, public_key.bytes, message)}