Module 0x1::ed25519
Contains functions for:
- Ed25519 digital signatures: i.e., EdDSA signatures over Edwards25519 curves with co-factor 8
- Struct
SignedMessage - Struct
UnvalidatedPublicKey - Struct
ValidatedPublicKey - Struct
Signature - Constants
- Function
new_unvalidated_public_key_from_bytes - Function
new_validated_public_key_from_bytes - Function
new_signature_from_bytes - Function
public_key_to_unvalidated - Function
public_key_into_unvalidated - Function
unvalidated_public_key_to_bytes - Function
validated_public_key_to_bytes - Function
signature_to_bytes - Function
public_key_validate - Function
signature_verify_strict - Function
signature_verify_strict_t - Function
new_signed_message - Function
unvalidated_public_key_to_authentication_key - Function
validated_public_key_to_authentication_key - Function
public_key_bytes_to_authentication_key - Function
public_key_validate_internal - Function
signature_verify_strict_internal - Specification
- Function
new_unvalidated_public_key_from_bytes - Function
new_validated_public_key_from_bytes - Function
new_signature_from_bytes - Function
public_key_validate - Function
signature_verify_strict - Function
signature_verify_strict_t - Function
new_signed_message - Function
unvalidated_public_key_to_authentication_key - Function
validated_public_key_to_authentication_key - Function
public_key_bytes_to_authentication_key - Function
public_key_validate_internal - Function
signature_verify_strict_internal - Helper functions
- Function
use 0x1::bcs;
use 0x1::error;
use 0x1::hash;
use 0x1::option;
use 0x1::type_info;
Struct 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
Struct 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>
Struct 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>
Struct 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>
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;
Function 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 }
}
Function 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>()
}
}
Function 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 }
}
Function 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
}
}
Function 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
}
}
Function 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
}
Function 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
}
Function 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
}
Function 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)
}
Function 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)
}
Function 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))
}
Function 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,
}
}
Function 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)
}
Function 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)
}
Function 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)
}
Function 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;
Function signature_verify_strict_internal
Return true if the Ed25519 signature on message verifies against the Ed25519 public_key.
Returns false if either:
signatureorpublic keyare of wrong sizespublic_keydoes not pass points-on-curve or not-in-small-subgroup checks,signaturedoes not pass points-on-curve or not-in-small-subgroup checks,- the signature on
messagedoes 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
Function 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;
}
Function 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>();
Function 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;
}
Function public_key_validate
public fun public_key_validate(pk: &ed25519::UnvalidatedPublicKey): option::Option<ed25519::ValidatedPublicKey>
pragma opaque;
aborts_if false;
let cond = spec_public_key_validate_internal(pk.bytes);
ensures cond ==> result == option::spec_some(ValidatedPublicKey { bytes: pk.bytes });
ensures !cond ==> result == option::spec_none<ValidatedPublicKey>();
Function signature_verify_strict
public fun signature_verify_strict(signature: &ed25519::Signature, public_key: &ed25519::UnvalidatedPublicKey, message: vector<u8>): bool
pragma opaque;
aborts_if false;
ensures result == spec_signature_verify_strict_internal(signature.bytes, public_key.bytes, message);
Function signature_verify_strict_t
public fun signature_verify_strict_t<T: drop>(signature: &ed25519::Signature, public_key: &ed25519::UnvalidatedPublicKey, data: T): bool
pragma opaque;
aborts_if !type_info::spec_is_struct<T>();
ensures result == spec_signature_verify_strict_t(signature, public_key, data);
Function new_signed_message
public fun new_signed_message<T: drop>(data: T): ed25519::SignedMessage<T>
pragma opaque;
aborts_if !type_info::spec_is_struct<T>();
ensures result == SignedMessage<T> { type_info: type_info::type_of<T>(), inner: data };
Function unvalidated_public_key_to_authentication_key
public fun unvalidated_public_key_to_authentication_key(pk: &ed25519::UnvalidatedPublicKey): vector<u8>
pragma opaque;
aborts_if false;
ensures result == spec_public_key_bytes_to_authentication_key(pk.bytes);
Function validated_public_key_to_authentication_key
public fun validated_public_key_to_authentication_key(pk: &ed25519::ValidatedPublicKey): vector<u8>
pragma opaque;
aborts_if false;
ensures result == spec_public_key_bytes_to_authentication_key(pk.bytes);
Function 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);
Function 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);
Function 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)
}