Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Spec] Add the initial specs for ed25519 and multi_ed25519 #5677

Merged
merged 1 commit into from
Dec 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions aptos-move/framework/aptos-stdlib/doc/ed25519.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ Contains functions for:
- [Function `public_key_validate_internal`](#0x1_ed25519_public_key_validate_internal)
- [Function `signature_verify_strict_internal`](#0x1_ed25519_signature_verify_strict_internal)
- [Specification](#@Specification_1)
- [Function `new_unvalidated_public_key_from_bytes`](#@Specification_1_new_unvalidated_public_key_from_bytes)
- [Function `new_validated_public_key_from_bytes`](#@Specification_1_new_validated_public_key_from_bytes)
- [Function `new_signature_from_bytes`](#@Specification_1_new_signature_from_bytes)
- [Function `public_key_validate_internal`](#@Specification_1_public_key_validate_internal)
- [Function `signature_verify_strict_internal`](#@Specification_1_signature_verify_strict_internal)

Expand Down Expand Up @@ -686,6 +689,82 @@ Returns <code><b>false</b></code> if either:
## Specification


<a name="@Specification_1_new_unvalidated_public_key_from_bytes"></a>

### Function `new_unvalidated_public_key_from_bytes`


<pre><code><b>public</b> <b>fun</b> <a href="ed25519.md#0x1_ed25519_new_unvalidated_public_key_from_bytes">new_unvalidated_public_key_from_bytes</a>(bytes: <a href="../../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;): <a href="ed25519.md#0x1_ed25519_UnvalidatedPublicKey">ed25519::UnvalidatedPublicKey</a>
</code></pre>




<pre><code><b>let</b> length = len(bytes);
<b>aborts_if</b> length != <a href="ed25519.md#0x1_ed25519_PUBLIC_KEY_NUM_BYTES">PUBLIC_KEY_NUM_BYTES</a>;
<b>ensures</b> result == <a href="ed25519.md#0x1_ed25519_UnvalidatedPublicKey">UnvalidatedPublicKey</a> { bytes };
</code></pre>



<a name="@Specification_1_new_validated_public_key_from_bytes"></a>

### Function `new_validated_public_key_from_bytes`


<pre><code><b>public</b> <b>fun</b> <a href="ed25519.md#0x1_ed25519_new_validated_public_key_from_bytes">new_validated_public_key_from_bytes</a>(bytes: <a href="../../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;): <a href="../../move-stdlib/doc/option.md#0x1_option_Option">option::Option</a>&lt;<a href="ed25519.md#0x1_ed25519_ValidatedPublicKey">ed25519::ValidatedPublicKey</a>&gt;
</code></pre>




<pre><code><b>aborts_if</b> <b>false</b>;
<b>let</b> cond = <a href="ed25519.md#0x1_ed25519_spec_public_key_validate_internal">spec_public_key_validate_internal</a>(bytes);
<b>ensures</b> cond ==&gt; result == <a href="../../move-stdlib/doc/option.md#0x1_option_spec_some">option::spec_some</a>(<a href="ed25519.md#0x1_ed25519_ValidatedPublicKey">ValidatedPublicKey</a>{bytes});
<b>ensures</b> !cond ==&gt; result == <a href="../../move-stdlib/doc/option.md#0x1_option_spec_none">option::spec_none</a>&lt;<a href="ed25519.md#0x1_ed25519_ValidatedPublicKey">ValidatedPublicKey</a>&gt;();
</code></pre>



<a name="@Specification_1_new_signature_from_bytes"></a>

### Function `new_signature_from_bytes`


<pre><code><b>public</b> <b>fun</b> <a href="ed25519.md#0x1_ed25519_new_signature_from_bytes">new_signature_from_bytes</a>(bytes: <a href="../../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;): <a href="ed25519.md#0x1_ed25519_Signature">ed25519::Signature</a>
</code></pre>




<pre><code><b>aborts_if</b> len(bytes)!= <a href="ed25519.md#0x1_ed25519_SIGNATURE_NUM_BYTES">SIGNATURE_NUM_BYTES</a>;
<b>ensures</b> result == <a href="ed25519.md#0x1_ed25519_Signature">Signature</a> { bytes };
</code></pre>




<a name="0x1_ed25519_spec_public_key_validate_internal"></a>


<pre><code><b>fun</b> <a href="ed25519.md#0x1_ed25519_spec_public_key_validate_internal">spec_public_key_validate_internal</a>(bytes: <a href="../../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;): bool;
</code></pre>




<a name="0x1_ed25519_spec_signature_verify_strict_internal"></a>


<pre><code><b>fun</b> <a href="ed25519.md#0x1_ed25519_spec_signature_verify_strict_internal">spec_signature_verify_strict_internal</a>(
signature: <a href="../../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;,
public_key: <a href="../../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;,
message: <a href="../../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;
): bool;
</code></pre>



<a name="@Specification_1_public_key_validate_internal"></a>

### Function `public_key_validate_internal`
Expand All @@ -698,6 +777,8 @@ Returns <code><b>false</b></code> if either:


<pre><code><b>pragma</b> opaque;
<b>aborts_if</b> <b>false</b>;
<b>ensures</b> result == <a href="ed25519.md#0x1_ed25519_spec_public_key_validate_internal">spec_public_key_validate_internal</a>(bytes);
</code></pre>


Expand All @@ -714,6 +795,8 @@ Returns <code><b>false</b></code> if either:


<pre><code><b>pragma</b> opaque;
<b>aborts_if</b> <b>false</b>;
<b>ensures</b> result == <a href="ed25519.md#0x1_ed25519_spec_signature_verify_strict_internal">spec_signature_verify_strict_internal</a>(signature, public_key, message);
</code></pre>


Expand Down
87 changes: 87 additions & 0 deletions aptos-move/framework/aptos-stdlib/doc/multi_ed25519.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ This module has the exact same interface as the Ed25519 module.
- [Function `public_key_validate_internal`](#0x1_multi_ed25519_public_key_validate_internal)
- [Function `signature_verify_strict_internal`](#0x1_multi_ed25519_signature_verify_strict_internal)
- [Specification](#@Specification_1)
- [Function `new_unvalidated_public_key_from_bytes`](#@Specification_1_new_unvalidated_public_key_from_bytes)
- [Function `new_validated_public_key_from_bytes`](#@Specification_1_new_validated_public_key_from_bytes)
- [Function `new_signature_from_bytes`](#@Specification_1_new_signature_from_bytes)
- [Function `public_key_validate_internal`](#@Specification_1_public_key_validate_internal)
- [Function `signature_verify_strict_internal`](#@Specification_1_signature_verify_strict_internal)

Expand Down Expand Up @@ -278,6 +281,7 @@ Parses the input bytes as a *validated* MultiEd25519 public key.


<pre><code><b>public</b> <b>fun</b> <a href="multi_ed25519.md#0x1_multi_ed25519_new_validated_public_key_from_bytes">new_validated_public_key_from_bytes</a>(bytes: <a href="../../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;): Option&lt;<a href="multi_ed25519.md#0x1_multi_ed25519_ValidatedPublicKey">ValidatedPublicKey</a>&gt; {
// Note that `public_key_validate_internal` will check that `<a href="../../move-stdlib/doc/vector.md#0x1_vector_length">vector::length</a>(&bytes) / <a href="multi_ed25519.md#0x1_multi_ed25519_INDIVIDUAL_PUBLIC_KEY_NUM_BYTES">INDIVIDUAL_PUBLIC_KEY_NUM_BYTES</a> &lt;= <a href="multi_ed25519.md#0x1_multi_ed25519_MAX_NUMBER_OF_PUBLIC_KEYS">MAX_NUMBER_OF_PUBLIC_KEYS</a>`.
<b>if</b> (<a href="../../move-stdlib/doc/vector.md#0x1_vector_length">vector::length</a>(&bytes) % <a href="multi_ed25519.md#0x1_multi_ed25519_INDIVIDUAL_PUBLIC_KEY_NUM_BYTES">INDIVIDUAL_PUBLIC_KEY_NUM_BYTES</a> == <a href="multi_ed25519.md#0x1_multi_ed25519_THRESHOLD_SIZE_BYTES">THRESHOLD_SIZE_BYTES</a> &&
<a href="multi_ed25519.md#0x1_multi_ed25519_public_key_validate_internal">public_key_validate_internal</a>(bytes)) {
<a href="../../move-stdlib/doc/option.md#0x1_option_some">option::some</a>(<a href="multi_ed25519.md#0x1_multi_ed25519_ValidatedPublicKey">ValidatedPublicKey</a> {
Expand Down Expand Up @@ -669,6 +673,85 @@ Returns <code><b>false</b></code> if either:
## Specification


<a name="@Specification_1_new_unvalidated_public_key_from_bytes"></a>

### Function `new_unvalidated_public_key_from_bytes`


<pre><code><b>public</b> <b>fun</b> <a href="multi_ed25519.md#0x1_multi_ed25519_new_unvalidated_public_key_from_bytes">new_unvalidated_public_key_from_bytes</a>(bytes: <a href="../../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;): <a href="multi_ed25519.md#0x1_multi_ed25519_UnvalidatedPublicKey">multi_ed25519::UnvalidatedPublicKey</a>
</code></pre>




<pre><code><b>let</b> length = len(bytes);
<b>aborts_if</b> length / <a href="multi_ed25519.md#0x1_multi_ed25519_INDIVIDUAL_PUBLIC_KEY_NUM_BYTES">INDIVIDUAL_PUBLIC_KEY_NUM_BYTES</a> &gt; <a href="multi_ed25519.md#0x1_multi_ed25519_MAX_NUMBER_OF_PUBLIC_KEYS">MAX_NUMBER_OF_PUBLIC_KEYS</a>;
<b>aborts_if</b> length % <a href="multi_ed25519.md#0x1_multi_ed25519_INDIVIDUAL_PUBLIC_KEY_NUM_BYTES">INDIVIDUAL_PUBLIC_KEY_NUM_BYTES</a> != <a href="multi_ed25519.md#0x1_multi_ed25519_THRESHOLD_SIZE_BYTES">THRESHOLD_SIZE_BYTES</a>;
<b>ensures</b> result == <a href="multi_ed25519.md#0x1_multi_ed25519_UnvalidatedPublicKey">UnvalidatedPublicKey</a> { bytes };
</code></pre>



<a name="@Specification_1_new_validated_public_key_from_bytes"></a>

### Function `new_validated_public_key_from_bytes`


<pre><code><b>public</b> <b>fun</b> <a href="multi_ed25519.md#0x1_multi_ed25519_new_validated_public_key_from_bytes">new_validated_public_key_from_bytes</a>(bytes: <a href="../../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;): <a href="../../move-stdlib/doc/option.md#0x1_option_Option">option::Option</a>&lt;<a href="multi_ed25519.md#0x1_multi_ed25519_ValidatedPublicKey">multi_ed25519::ValidatedPublicKey</a>&gt;
</code></pre>




<pre><code><b>aborts_if</b> len(bytes) % <a href="multi_ed25519.md#0x1_multi_ed25519_INDIVIDUAL_PUBLIC_KEY_NUM_BYTES">INDIVIDUAL_PUBLIC_KEY_NUM_BYTES</a> == <a href="multi_ed25519.md#0x1_multi_ed25519_THRESHOLD_SIZE_BYTES">THRESHOLD_SIZE_BYTES</a>
&& len(bytes) / <a href="multi_ed25519.md#0x1_multi_ed25519_INDIVIDUAL_PUBLIC_KEY_NUM_BYTES">INDIVIDUAL_PUBLIC_KEY_NUM_BYTES</a> &gt; <a href="multi_ed25519.md#0x1_multi_ed25519_MAX_NUMBER_OF_PUBLIC_KEYS">MAX_NUMBER_OF_PUBLIC_KEYS</a>;
<b>let</b> cond = len(bytes) % <a href="multi_ed25519.md#0x1_multi_ed25519_INDIVIDUAL_PUBLIC_KEY_NUM_BYTES">INDIVIDUAL_PUBLIC_KEY_NUM_BYTES</a> == <a href="multi_ed25519.md#0x1_multi_ed25519_THRESHOLD_SIZE_BYTES">THRESHOLD_SIZE_BYTES</a>
&& <a href="multi_ed25519.md#0x1_multi_ed25519_spec_public_key_validate_internal">spec_public_key_validate_internal</a>(bytes);
<b>ensures</b> cond ==&gt; result == <a href="../../move-stdlib/doc/option.md#0x1_option_spec_some">option::spec_some</a>(<a href="multi_ed25519.md#0x1_multi_ed25519_ValidatedPublicKey">ValidatedPublicKey</a>{bytes});
<b>ensures</b> !cond ==&gt; result == <a href="../../move-stdlib/doc/option.md#0x1_option_spec_none">option::spec_none</a>&lt;<a href="multi_ed25519.md#0x1_multi_ed25519_ValidatedPublicKey">ValidatedPublicKey</a>&gt;();
</code></pre>



<a name="@Specification_1_new_signature_from_bytes"></a>

### Function `new_signature_from_bytes`


<pre><code><b>public</b> <b>fun</b> <a href="multi_ed25519.md#0x1_multi_ed25519_new_signature_from_bytes">new_signature_from_bytes</a>(bytes: <a href="../../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;): <a href="multi_ed25519.md#0x1_multi_ed25519_Signature">multi_ed25519::Signature</a>
</code></pre>




<pre><code><b>aborts_if</b> len(bytes) % <a href="multi_ed25519.md#0x1_multi_ed25519_INDIVIDUAL_SIGNATURE_NUM_BYTES">INDIVIDUAL_SIGNATURE_NUM_BYTES</a> != <a href="multi_ed25519.md#0x1_multi_ed25519_BITMAP_NUM_OF_BYTES">BITMAP_NUM_OF_BYTES</a>;
<b>ensures</b> result == <a href="multi_ed25519.md#0x1_multi_ed25519_Signature">Signature</a> { bytes };
</code></pre>




<a name="0x1_multi_ed25519_spec_public_key_validate_internal"></a>


<pre><code><b>fun</b> <a href="multi_ed25519.md#0x1_multi_ed25519_spec_public_key_validate_internal">spec_public_key_validate_internal</a>(bytes: <a href="../../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;): bool;
</code></pre>




<a name="0x1_multi_ed25519_spec_signature_verify_strict_internal"></a>


<pre><code><b>fun</b> <a href="multi_ed25519.md#0x1_multi_ed25519_spec_signature_verify_strict_internal">spec_signature_verify_strict_internal</a>(
multisignature: <a href="../../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;,
public_key: <a href="../../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;,
message: <a href="../../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;
): bool;
</code></pre>



<a name="@Specification_1_public_key_validate_internal"></a>

### Function `public_key_validate_internal`
Expand All @@ -681,6 +764,8 @@ Returns <code><b>false</b></code> if either:


<pre><code><b>pragma</b> opaque;
<b>aborts_if</b> len(bytes) / <a href="multi_ed25519.md#0x1_multi_ed25519_INDIVIDUAL_PUBLIC_KEY_NUM_BYTES">INDIVIDUAL_PUBLIC_KEY_NUM_BYTES</a> &gt; <a href="multi_ed25519.md#0x1_multi_ed25519_MAX_NUMBER_OF_PUBLIC_KEYS">MAX_NUMBER_OF_PUBLIC_KEYS</a>;
<b>ensures</b> result == <a href="multi_ed25519.md#0x1_multi_ed25519_spec_public_key_validate_internal">spec_public_key_validate_internal</a>(bytes);
</code></pre>


Expand All @@ -697,6 +782,8 @@ Returns <code><b>false</b></code> if either:


<pre><code><b>pragma</b> opaque;
<b>aborts_if</b> <b>false</b>;
<b>ensures</b> result == <a href="multi_ed25519.md#0x1_multi_ed25519_spec_signature_verify_strict_internal">spec_signature_verify_strict_internal</a>(multisignature, public_key, message);
</code></pre>


Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,53 @@
spec aptos_std::ed25519 {
spec public_key_validate_internal {
// TODO: temporary mockup.

// -----------------------
// Function specifications
// -----------------------

spec new_unvalidated_public_key_from_bytes(bytes: vector<u8>): UnvalidatedPublicKey {
let length = len(bytes);
aborts_if length != PUBLIC_KEY_NUM_BYTES;
ensures result == UnvalidatedPublicKey { bytes };
}

spec new_validated_public_key_from_bytes(bytes: vector<u8>): Option<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>();
}

spec new_signature_from_bytes(bytes: vector<u8>): Signature {
aborts_if len(bytes)!= SIGNATURE_NUM_BYTES;
ensures result == Signature { bytes };
}


// ----------------
// Native functions
// ----------------

spec fun spec_public_key_validate_internal(bytes: vector<u8>): bool;

spec fun spec_signature_verify_strict_internal(
signature: vector<u8>,
public_key: vector<u8>,
message: vector<u8>
): bool;

spec public_key_validate_internal(bytes: vector<u8>): bool {
pragma opaque;
aborts_if false;
ensures result == spec_public_key_validate_internal(bytes);
}

spec signature_verify_strict_internal {
// TODO: temporary mockup.
spec 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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ module aptos_std::multi_ed25519 {

/// Parses the input bytes as a *validated* MultiEd25519 public key.
public fun new_validated_public_key_from_bytes(bytes: vector<u8>): Option<ValidatedPublicKey> {
// Note that `public_key_validate_internal` will check that `vector::length(&bytes) / INDIVIDUAL_PUBLIC_KEY_NUM_BYTES <= MAX_NUMBER_OF_PUBLIC_KEYS`.
if (vector::length(&bytes) % INDIVIDUAL_PUBLIC_KEY_NUM_BYTES == THRESHOLD_SIZE_BYTES &&
public_key_validate_internal(bytes)) {
option::some(ValidatedPublicKey {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,56 @@
spec aptos_std::multi_ed25519 {
spec public_key_validate_internal {
// TODO: temporary mockup.

// -----------------------
// Function specifications
// -----------------------

spec new_unvalidated_public_key_from_bytes(bytes: vector<u8>): UnvalidatedPublicKey {
let length = len(bytes);
aborts_if length / INDIVIDUAL_PUBLIC_KEY_NUM_BYTES > MAX_NUMBER_OF_PUBLIC_KEYS;
aborts_if length % INDIVIDUAL_PUBLIC_KEY_NUM_BYTES != THRESHOLD_SIZE_BYTES;
ensures result == UnvalidatedPublicKey { bytes };
}

spec new_validated_public_key_from_bytes(bytes: vector<u8>): Option<ValidatedPublicKey> {
aborts_if len(bytes) % INDIVIDUAL_PUBLIC_KEY_NUM_BYTES == THRESHOLD_SIZE_BYTES
&& len(bytes) / INDIVIDUAL_PUBLIC_KEY_NUM_BYTES > MAX_NUMBER_OF_PUBLIC_KEYS;
let cond = len(bytes) % INDIVIDUAL_PUBLIC_KEY_NUM_BYTES == THRESHOLD_SIZE_BYTES
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How come you don't do the length / INDIVIDUAL_PUBLIC_KEY_NUM_BYTES > MAX_NUMBER_OF_PUBLIC_KEYS check here too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alinush , cond is here to model the condition in this line: https://github.com/aptos-labs/aptos-core/blob/main/aptos-move/framework/aptos-stdlib/sources/cryptography/multi_ed25519.move#L123

Does the Move function new_validated_public_key_from_bytes actually need the additional check you're mentioning?

Copy link
Contributor

@alinush alinush Nov 30, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see: That check is done in the public_key_validate_internal native, which new_validated_public_key_from_bytes calls. I guess that's why I didn't replicate it.

A bit confusing now reading my own code 🤦 ...

Would you mind adding a comment at line 123 (which you linked to) that says:

// Note that `public_key_validate_internal` will check that `vector::length(&bytes) / INDIVIDUAL_PUBLIC_KEY_NUM_BYTES <= MAX_NUMBER_OF_PUBLIC_KEYS`

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Added the comment.

Copy link
Contributor

@alinush alinush Dec 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @junkil-park, I was taking another look, and now I noticed that you added the length / INDIVIDUAL_PUBLIC_KEY_NUM_BYTES > MAX_NUMBER_OF_PUBLIC_KEYS check here too.

But, as per my new comment below, this abort will never happen because the native called by new_validated_public_key_from_bytes would only returns false, not abort.

&& spec_public_key_validate_internal(bytes);
ensures cond ==> result == option::spec_some(ValidatedPublicKey{bytes});
ensures !cond ==> result == option::spec_none<ValidatedPublicKey>();
}

spec new_signature_from_bytes(bytes: vector<u8>): Signature {
aborts_if len(bytes) % INDIVIDUAL_SIGNATURE_NUM_BYTES != BITMAP_NUM_OF_BYTES;
ensures result == Signature { bytes };
}


// ----------------
// Native functions
// ----------------

spec fun spec_public_key_validate_internal(bytes: vector<u8>): bool;

spec fun spec_signature_verify_strict_internal(
multisignature: vector<u8>,
public_key: vector<u8>,
message: vector<u8>
): bool;

spec public_key_validate_internal(bytes: vector<u8>): bool {
pragma opaque;
aborts_if len(bytes) / INDIVIDUAL_PUBLIC_KEY_NUM_BYTES > MAX_NUMBER_OF_PUBLIC_KEYS;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @junkil-park, I see this says that the native aborts upon this condition, but the native never aborts.
See

Copy link
Contributor

@alinush alinush Dec 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think my initial reply in the discussion above made it seem like the native aborts upon this condition, but it merely returns false.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ensures result == spec_public_key_validate_internal(bytes);
}

spec signature_verify_strict_internal {
// TODO: temporary mockup.
spec signature_verify_strict_internal(
multisignature: vector<u8>,
public_key: vector<u8>,
message: vector<u8>
): bool {
pragma opaque;
aborts_if false;
ensures result == spec_signature_verify_strict_internal(multisignature, public_key, message);
}
}
2 changes: 1 addition & 1 deletion aptos-move/framework/aptos-token/doc/token.md
Original file line number Diff line number Diff line change
Expand Up @@ -1141,7 +1141,7 @@ The field is not mutable
Withdraw capability doesn't have sufficient amount


<pre><code><b>const</b> <a href="token.md#0x3_token_EINSUFFICIENT_WITHDRAW_CAPABILITY_AMOUNT">EINSUFFICIENT_WITHDRAW_CAPABILITY_AMOUNT</a>: u64 = 37;
<pre><code><b>const</b> <a href="token.md#0x3_token_EINSUFFICIENT_WITHDRAW_CAPABILITY_AMOUNT">EINSUFFICIENT_WITHDRAW_CAPABILITY_AMOUNT</a>: u64 = 38;
</code></pre>


Expand Down