Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/erhant/polenta

A toy language to play around with polynomials over finite fields.
https://github.com/erhant/polenta

cryptography lambdaworks pest polynomials repl rust

Last synced: 4 days ago
JSON representation

A toy language to play around with polynomials over finite fields.

Awesome Lists containing this project

README

        

# Polenta

![Crates.io Version](https://img.shields.io/crates/v/polenta)
![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/erhant/polenta/tests.yml?label=tests)
![Crates.io License](https://img.shields.io/crates/l/polenta)

Polenta is a toy polynomial arithmetic language, and **everything** is a polynomial. As such, it is more suited towards having fun instead of having performance.

## Features

- [x] Polynomial arithmetic using [lambdaworks](https://github.com/lambdaclass/lambdaworks)
- [x] REPL to play around with
- [x] `let` and `assert` expressions
- [ ] `prove` and `commit` expressions
- [ ] selecting fields

> The project mostly started to learn more about Pest, and it is a lovely project! See for more!

## Installation

You can add the [crate](https://crates.io/crates/polenta) with:

```sh
cargo add polenta
```

You can install the REPL with:

```sh
cargo install polenta --features="repl"
```

## Usage

In this section we go over what can be done with Polenta.

> All code shown below are valid Polenta code. To follow along, you can use the REPL installed above!

### Statements

You can use Polenta as a calculator-over-field.

```rs
> 10 - 2^3 * 2;
18446744069414584315
```

However, you should keep in mind that all operations are defined over the field, so division might not always work as you expect:

```rs
> 1 / 2; // some number x such that 2*x = 1, not 0.5!
9223372034707292161
```

> Polenta supports single line comments using `//`, as shown above.

### Creating a Polynomial

A polynomial is created by specifying its terms.

```rs
> let P(x) = 3*x^2 + 5;
3*x^2 + 5
```

Behind the scenes all terms are considered a monomial, and they are composed together. As such, you can repeat a term with the same degree and the result will have them added up:

```rs
> let P(x) = 3*x^2 + 2*x^2 + 1*x^2;
6*x^2
> let Q(x) = 5*x - 5*x + 1;
1
```

You can also multiply polynomials:

```rs
> let P(x) = (x + 1)*(x + 2)*(x + 4);
x^3 + 7*x^2 + 14*x + 8
```

You can create a polynomial from an existing one:

```rs
> let P(x) = 3*x;
3*x
> let Q(x) = P^2 + 2*P;
9*x^2 + 6*x
```

Shadowing is allowed:

```rs
> let P(x) = 3*x;
3*x
> let P(x) = 3*P + 5;
9*x + 5
```

You can use an identifier within a polynomial, but if the identifier has the same name as the term, it will be ignored.

```rs
> let t = 2;
> let x = 5;
> let P(x) = x^t + 2*x;
x^2 + 2*x
```

### Equality

Polenta has `==` and `!=` operators that return either a 1 or 0 based on the equality.

```rs
> 2 == 3
0
> let P(x) = 2*x
2*x
> let Q(x) = 3*x - x
2*x
> P == Q
1
```

### Evaluating a Polynomial

Evaluation is achieved using a binary operation `@`, so that `P@2` means "evaluate polynomial `P` at point `2`.

```rs
> let P(x) = 3*x;
3*x
> let z = P@3;
9
> let Q(x) = x^z + z*x;
x^9 + 9*x
```

Remember that everything is a polynomial in Polenta, so you could evaluate a number as well. Evaluation will not have an effect because a number is treated as a constant polynomial.

```rs
> 4@2
4
```

Since evaluation is a binary operation, you can chain them together:

```rs
> let P(x) = 3*x + 1;
3*x + 1
> let Q(x) = x/2;
9223372034707292161*x
> Q@P@Q@P@3; // Q(P(Q(P(3))))
8
```

### Assertions

You can make assertions within Polenta for safety, where a failed assertion throws an `AssertionError`.
An assertion fails if the expression that they are given is a zero polynomial.

```rs
> assert 1
1
> assert 0
× Assertion Failed

> assert 43
43
```

### Errors in REPL

While using REPL, if there is an error you will see it on screen with clear logs.

```sh
> let x = idontexist;
× Unknown Identifier: idontexist
> 5/0;
× Division by Zero
> let a = ++syntaxerror--;
× Syntax Error
╭─[input:1:9]
1 │ let a = ++syntaxerror--;
· ─
╰────
help: Expected one of [expr], got []
```

## Testing

Run all tests with:

```sh
cargo test
```

## License

Polenta is MIT licensed.