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

Add ByteArray builtin and Byte literal #2865

Closed
Tracked by #1283
paulcadman opened this issue Jun 27, 2024 · 1 comment
Closed
Tracked by #1283

Add ByteArray builtin and Byte literal #2865

paulcadman opened this issue Jun 27, 2024 · 1 comment
Labels
Milestone

Comments

@paulcadman
Copy link
Collaborator

This issue proposes the introduction of a builtin Bytes type for use by Anoma and the Core evaluator that represents an array of bytes.

This is desirable for the Anoma backend for two main reasons.

  1. We currently represent arrays of bytes as a Nat in the Anoma backend (an integer atom). This is ambiguous, for example the byte arrays { 0x10 }, { 0x10, 0x00 }, { 0x10, 0x00, 0x00 } (and any byte arrays that differ only by trailing zeroed bytes) are all encoded to the same integer (Anoma uses little endian encoding).

  2. We'd prefer to use a more specific type (than Nat) for values that we want to interpret as bytes (in a Juvix program or on the Anoma stdlib APIs). It doesn't make sense for a user to perform arithmetic on a cryptographic signature for example.

In Anoma we have the following builtin:

axiom anomaSign : {A : Type} -> A -> Nat -> Nat; 

This signs a message using a private key, it returns a signed message.

In Juvix programs the private key is provided as a Nat literal, e.g:

privKey : Nat := 0x3181f891cd2323ffe802dd8f36f7e77cd072e3bd8f49884e8b38a297646351e9015535fa1125ec092c85758756d51bf29eed86a118942135c1657bf4cb5c6fc9;

The reason Nat is used is because these data are represented as atoms in the nockma backend.

In Juvix programs we would like a more precise type to represent public, private keys and signatures. In Anoma Node these cryptographic functions actually operate on binary atoms.

Bytes builtin Proposal

The builtin bytes type:

builtin bytes
axiom Bytes : Type;

The type of anomaSign would be:

anomaSign : {A : Type} -> Bytes -> Bytes

We need support for byte literals, the following syntax is proposed:

privKey : Bytes := Bytes#[0x31; 0x81; 0xf8; 0x91; 0xcd; 0x23; 0x23; 0xff; 0xe8; 0x2; 0xdd; 0x8f; 0x36; 0xf7; 0xe7; 0x7c; 0xd0; 0x72; 0xe3; 0xbd; 0x8f; 0x49; 0x88; 0x4e; 0x8b; 0x38; 0xa2; 0x97; 0x64; 0x63; 0x51; 0xe9; 0x1; 0x55; 0x35; 0xfa; 0x11; 0x25; 0xec; 0x9; 0x2c; 0x85; 0x75; 0x87; 0x56; 0xd5; 0x1b; 0xf2; 0x9e; 0xed; 0x86; 0xa1; 0x18; 0x94; 0x21; 0x35; 0xc1; 0x65; 0x7b; 0xf4; 0xcb; 0x5c; 0x6f; 0xc9]

Each element of the Bytes#[] list must be an integer literal (decimal or hex).

It's a compile-time error to use integer literals that don't fit into a byte:

-- error: 300 does not fit into one byte.
err : Bytes := Bytes#[300];

Backend Representation

Core

A new ConstantValue will be added ConstBytes !ByteString.

Nockma

Constant bytes will be transformed to a Nock cell with the head containing the length of the bytes and the tail containing the bytes payload, I.e the integer representing the bytes with little-endian byte ordering.

Calling Anoma stdlib functions in the nockma backend.

Anoma stdlib functions like sign, verify must be passed the the integer representing the bytes payload only (i.e without the length) for public, private key and signature arguments (these have a fixed length). In order to make these calls compatible with the proposed Bytes Nockma representation the payload (i.e the tail of the bytes cell) will be projected before calling the stdlib function.

The sign function returns a bytes payload representing a cryptographic signature. It is known to represent 64 bytes so the backend call will wrap the result in a cell with head value 64.

Native, Cairo

The design of the representation of Bytes is deferred.

@paulcadman paulcadman modified the milestones: 0.6.3, 0.6.4 Jun 27, 2024
@paulcadman paulcadman modified the milestones: 0.6.4, 0.6.5 Jul 19, 2024
paulcadman added a commit that referenced this issue Aug 2, 2024
This PR adds `Byte` as a builtin with builtin functions for equality,
`byte-from-nat` and `byte-to-nat`. The standard library is updated to
include this definition with instances for `FromNatural`, `Show` and
`Eq` traits.

The `FromNatural` trait means that you can assign `Byte` values using
non-negative numeric literals.


You can use byte literals in jvc files by adding the u8 suffix to a
numeric value. For example, 1u8 represents a byte literal.

Arithmetic is not supported as the intention is for this type to be used
to construct ByteArrays of data where isn't not appropriate to modify
using arithmetic operations. We may add a separate `UInt8` type in the
future which supports arithmetic.

The Byte is supported in the native, rust and Anoma backend. Byte is not
supported in the Cairo backend because `byte-from-nat` cannot be
defined.

The primitive builtin ops for `Byte` are called `OpUInt8ToInt` and
`OpUInt8FromInt`, named because these ops work on integers and in future
we may reuse these for a separate unsigned 8-bit integer type that
supports arithmetic.

Part of:

* #2865
@paulcadman
Copy link
Collaborator Author

@paulcadman paulcadman changed the title Add Bytes builtin and Bytes literal Add ByteArray builtin and Bytes literal Aug 14, 2024
@paulcadman paulcadman changed the title Add ByteArray builtin and Bytes literal Add ByteArray builtin and Byte literal Aug 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant