Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into PARTNER-214-SEP-6
Browse files Browse the repository at this point in the history
# Conflicts:
#	ecosystem/sep-0006.md
  • Loading branch information
Ifropc committed Feb 21, 2024
2 parents daaf9cd + 773af47 commit 0d643f1
Show file tree
Hide file tree
Showing 5 changed files with 253 additions and 16 deletions.
14 changes: 5 additions & 9 deletions core/cap-0051.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,13 +190,9 @@ Regarding base64 url encoding, it is possible to embed a small and efficient
fixed width base64 url encoder into a contract.

Regarding JSON, it has not been proven feasible to include a complete JSON
decoder or encoder, but given the JSON format, it is feasible to search the
client data JSON for the base64 url encoded challenge surrounded by `"`, and
then surrounded by either `:`, `,`, ` `, `{`, or `}`. Assuming consistency with
which clients produce the client data JSON it is also possible to check the
prefix of the client data JSON contains an exact format including the base64 url
encoded challenge. **(TODO: This paragraph is incorrect and needs replacing with
nother solution.)**
decoder or encoder, and as such implementing webauthn verification is also
dependent on the addition of a JSON host function interface that is out-of-scope
of this proposal.

## Protocol Upgrade Transition

Expand Down Expand Up @@ -231,7 +227,7 @@ reasons, such as resource cost or privacy.
### Audited Implementations

The only ECDSA secp256r1 pure-Rust crates that the Soroban environment could
embed are the [p256] and [ECDSA] crates. The two crates have never been
embed are the [p256] and [ecdsa] crates. The two crates have never been
independently audited.

## Test Cases
Expand All @@ -244,5 +240,5 @@ None yet. But will be tracked by [stellar/rs-sorovan-env#807] if implemented.

[Webauthn]: https://www.w3.org/TR/webauthn-2/
[p256]: https://crates.io/crates/p256
[ECDSA]: https://crates.io/crates/ECDSA
[ecdsa]: https://crates.io/crates/ecdsa
[stellar/rs-soroban-env#807]: https://github.com/stellar/rs-soroban-env/issues/807
208 changes: 208 additions & 0 deletions core/cap-0052.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
```
CAP: 0052
Title: Smart Contract Host Functionality: Base64 Encoding/Decoding
Working Group:
Owner: Leigh McCulloch <@leighmcculloch>
Authors: Leigh McCulloch <@leighmcculloch>
Consulted:
Status: Draft
Created: 2023-02-15
Discussion: TBD
Protocol version: TBD
```

## Simple Summary

Support base64 encoding/decoding in Soroban contracts via the exported host
interface.

## Motivation

Base64 encoding/decoding is a common encoding of binary data, especially within
data formatted as JSON. Encoding and decoding base64 is something that can be
done in contract code under the limits known today, relatively efficiently.

For example, a single small encode of 32 bytes to 43 bytes is about 200,000
instructions and about 460 bytes of additional code.

Even though base64 encoding can be done relatively easily for the case of small
data, in applications that need to encode or decode larger amounts of data it
quickly become a larger percentage of an applications work.

Additionally, even if efficient, this is a common standard that is simple to
encode host side and available in many standard libraries today.

An expected use of the base64 encode/decode is in the implementation of a
webauthn contract, where base64 url encoding is used.

### Goals Alignment

This CAP is aligned with the following Stellar Network Goals:

- The Stellar Network should make it easy for developers of Stellar projects to
create highly usable products

## Abstract

This proposal adds two functions to the Soroban environment's exported interface
that accepts the parameters for configuring a variant of base64, and encode and
decode bytes to and from base64 as specified in [RFC4648].

## Specification

A new function `base64_encode` with export name `n` in module `b` is added to
the Soroban environment's exported interface. It accepts an `alphabet`,
`padding`, and returns the bytes encoded in base64.

Another new function `base64_decode` with export name `o` in module `b` is added
to the Soroban environment's exported interface. It accepts an `alphabet`,
`padding`, and returns the bytes decoded. If the decode fails for any reason it
returns an `ScError`.

For both functions the parameters behave the same.

Parameter `alphabet` specifies the alphabet used by the encoder and decoder. The
symbols `std` or `url` are accepted, where they map respectively to the standard
alphabet and the URL and filename friendly alphabet as specified in [RFC4648].

Parameter `padding` specifies the padding character with the same limitations on
valid values as specified in [RFC4648]. The padding character is 8-bit, and is
stored in the lower 8-bits of the U32Val type. If the padding value of
0xffffffff is used it indicates no padding is to be used when encoding, and no
padding is required when decoding, but padding is permitted, unless strict is
specified.

Parameter `strict` specifies for decoding whether incomplete, non-existent, or
present-when-unspected padding should be considered an error. If strict is
specified then any padding that doesn't exactly match the padding that's
required would cause an error.

```diff mddiffcheck.ignore=true mddiffcheck.base=v20.1.0
--- a/soroban-env-common/env.json
+++ b/soroban-env-common/env.json
@@ -1890,6 +1890,38 @@
],
"return": "U32Val",
"docs": "Return the index of a Symbol in an array of linear-memory byte-slices, or trap if not found."
+ },
+ {
+ "export": "n",
+ "name": "base64_encode",
+ "args": [
+ {
+ "name": "input",
+ "type": "BytesObject"
+ },
+ {
+ "name": "alphabet",
+ "type": "Symbol"
+ },
+ {
+ "name": "padding",
+ "type": "U32Val"
+ }
+ ],
+ "return": "BytesObject",
+ "docs": "Base64 encodes as specified in RFC4648 the input BytesObject, using the alphabet specified as a symbol 'std' or 'url' that respectively encode with the standard alphabet or the URL/filename-safe alphabet, padded with the u8 byte stored in the low 8-bits of the padding U32Val, or not padded if the padding is 0xffffffff, returning a BytesObject with the encoded value."
+ },
+ {
+ "export": "o",
+ "name": "base64_decode",
+ "args": [
+ {
+ "name": "input",
+ "type": "BytesObject"
+ },
+ {
+ "name": "alphabet",
+ "type": "Symbol"
+ },
+ {
+ "name": "padding",
+ "type": "U32Val"
+ },
+ {
+ "name": "strict",
+ "type": "Bool"
+ }
+ ],
+ "return": "BytesObject",
+ "docs": "Base64 decodes as specified in RFC4648 the input BytesObject, using the alphabet specified as a symbol 'std' or 'url' that respectively encode with the standard alphabet or the URL/filename-safe alphabet, expecting padding with the u8 byte stored in the low 8-bits of the padding U32Val, or not padded if the padding is 0xffffffff, returning a BytesObject with the encoded value. If strict is specified, decoding fails if trailing padding is not exactly the number of bits required to pad. If decoding fails, the function returns ScError."
}
]
},
```

### Design Rationale

#### Alphabet

The alphabet's included are commonly used. Standard base64 encoding is most
commonly used in applications. Base64 url encoding is less commonly used, but is
used in the webauthn standard.

No custom alphabets are supported because their use is rare, however support for
custom alphabets could be added in the future by allowing for a 64 byte String
or Bytes value to be passed as the alphabet instead of a Symbol. The use of
Symbol to signal `std` or `url` is compact and efficient for known alphabets and
makes those selections distinct from the provision of a custom String alphabet
in the future.

#### Webauthn / Passkeys

The base64 encode/decode interface is largely motivated by the webauthn use
case. Webauthn involves an application and device holding a key and using that
key for authentication and authorization. The messages that Webauthn signs are
JSON and contain a base64 url encoded challenge value.

To implement Webauthn on Stellar in Soroban custom account contracts the
challenge would be the hash of an authorization entry. Webauthn base64 url
encodes it and the contract that does verification would either need to be able
to decode the challenge value to compare with the value it expects, or be able
to encode the value it expects to compare with the encoded value found in the
JSON message.

For example, a client data JSON:
```json
{
"type":"webauthn.get",
"challenge":"hJHFvaaoU7qkcH9kML46shLL_btpYGCA6ty3ie0M1Qw",
"origin":"http://localhost:4507",
"crossOrigin":false
}
```

## Protocol Upgrade Transition

### Backwards Incompatibilities

This proposal is completely backwards compatible.

### Resource Utilization

#### Metering

The new functions must be appropriately metered.

## Security

### Strict

Some applications that use base64 require that their base64 decoders are strict
in regards to the presence or non-presence of padding. Applications that fall
into this category may be applications that need to ensure that data encoded
always has a single representation in the encoded form. For this reason it is
relatively important that the variants supported include the ability to require
that decoding fail if indicated by the application that strict decoding is
required.

## Test Cases

None yet.

## Implementation

None yet.

[Webauthn]: https://www.w3.org/TR/webauthn-2/
[RFC4648]: https://rfc-editor.org/rfc/rfc4648.html
11 changes: 7 additions & 4 deletions ecosystem/sep-0001.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ Title: Stellar Info File
Author: stellar.org
Status: Active
Created: 2017-10-30
Updated: 2022-05-27
Version: 2.5.0
Updated: 2024-02-01
Version: 2.6.0
```

## Simple Summary
Expand Down Expand Up @@ -114,11 +114,14 @@ The public key in the verification photo should be the issuing public key for th

These fields go in the `stellar.toml` `[[CURRENCIES]]` list, one set of fields for each currency supported. Complete all applicable fields, and exclude any that don't apply.

Currencies can be Stellar Assets that have been issued by a Stellar account and share the same common behaviors, or custom token contracts that satisfy the SEP-41 interface but implementation and behavior is customizable.

Field | Requirements | Description
------|--------------|------------
code | string (<= 12 char) | Token code
code | string (<= 12 char) | Token code. Required.
issuer | `G...` string | Stellar public key of the issuing account. Required for tokens that are Stellar Assets. Omitted if the token is not a Stellar asset.
contract | `C...` string | Contract ID of the token contract. The token must be compatible with the [SEP-41 Token Interface](sep-0041.md) to be defined here. Required for tokens that are not Stellar Assets. Omitted if the token is a Stellar Asset.
code_template | string (<= 12 char) | A pattern with `?` as a single character wildcard. Allows a `[[CURRENCIES]]` entry to apply to multiple assets that share the same info. An example is futures, where the only difference between issues is the date of the contract. E.g. `CORN????????` to match codes such as `CORN20180604`.
issuer | `G...` string | Token issuer Stellar public key
status | string | Status of token. One of `live`, `dead`, `test`, or `private`. Allows issuer to mark whether token is dead/for testing/for private use or is live and should be listed in live exchanges.
display_decimals | int (0 to 7) | Preference for number of decimals to show when a client displays currency balance
name | string (<= 20 char) | A short name for the token
Expand Down
Loading

0 comments on commit 0d643f1

Please sign in to comment.