Skip to content

Commit

Permalink
feat: add v11 op code mimc
Browse files Browse the repository at this point in the history
  • Loading branch information
boblat committed Jan 20, 2025
1 parent 479cf70 commit b50ab7e
Show file tree
Hide file tree
Showing 19 changed files with 455 additions and 457 deletions.
57 changes: 57 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Contributing to Puya-ts

Contributions are welcome. For new features, please open an issue to discuss first.

## Workflow

We use [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/#summary). User-facing changes should include at least one `fix:` or `feat:` commit for release notes. Other conventions like `docs:` or `test:` are optional but helpful.

## Local Development

To set up the project locally:

1. **Install Node.js**: Download from [nodejs.org](https://nodejs.org/).

1. **Install Python 3.12+**.

1. **Install Puya**:

```sh
pipx install puyapy --python 3.12.6
```

1. **Install AlgoKit CLI**: Follow the guide from [Algokit](https://github.com/algorandfoundation/algokit-cli?tab=readme-ov-file#install).

1. **Start localnet**:

```sh
algokit localnet start
# or `algokit localnet reset --update` to update localnet docker images
```

1. **Install npm dependencies**:

```sh
npm install
```

1. **Run tests**:
```sh
npm test
```

## Adding New Op Codes for New AVM Versions

1. Copy the latest [langspec.puya.json](./langspec.puya.json) from [puya](https://github.com/algorandfoundation/puya/blob/main/langspec.puya.json). Refer to the [contributing guide](https://github.com/algorandfoundation/puya/blob/main/CONTRIBUTING.md#updating-langspec-for-new-avm-versions) on the Puya repo for more information on how the file itself is updated for a new AVM version.

2. Run the following scripts to update relevant files:

```sh
npm run script:op-metadata
npm run script:op-types
npm run script:op-ptypes
```

3. If a new `enum` type is required, add it to [ENUMS_TO_EXPOSE](./scripts/build-op-module.ts#L12). Re-run the scripts and update [index.ts](./packages/algo-ts/src/index.ts#L17).

4. Add an approval test to ensure the new op codes compile correctly; e.g., [AVM 11 approval test](./tests/approvals/avm11.algo.ts).
71 changes: 66 additions & 5 deletions langspec.puya.json
Original file line number Diff line number Diff line change
Expand Up @@ -3753,7 +3753,7 @@
"value": 1700,
"doc": "1700"
},
"min_avm_version": 11,
"min_avm_version": 12,
"halts": false,
"mode": "any",
"groups": ["Cryptography"],
Expand Down Expand Up @@ -5151,6 +5151,49 @@
],
"stack_outputs": []
},
"mimc": {
"name": "mimc",
"code": 230,
"size": 2,
"doc": [
"MiMC hash of scalars A, using curve and parameters specified by configuration C",
"A is a list of concatenated 32 byte big-endian unsigned integer scalars. Fail if A's length is not a multiple of 32 or any element exceeds the curve modulus.",
"",
"The MiMC hash function has known collisions since any input which is a multiple of the elliptic curve modulus will hash to the same value. MiMC is thus not a general purpose hash function, but meant to be used in zero knowledge applications to match a zk-circuit implementation."
],
"cost": {
"value": null,
"doc": "BN254Mp110=10 + 550 per 32 bytes of A; BLS12_381Mp111=10 + 550 per 32 bytes of A"
},
"min_avm_version": 11,
"halts": false,
"mode": "any",
"groups": ["Cryptography"],
"stack_inputs": [
{
"name": "A",
"stack_type": "[]byte",
"doc": null
}
],
"immediate_args": [
{
"name": "C",
"immediate_type": "arg_enum",
"arg_enum": "Mimc Configurations",
"modifies_stack_input": null,
"modifies_stack_output": null,
"doc": "configuration index"
}
],
"stack_outputs": [
{
"name": "X",
"stack_type": "[32]byte",
"doc": null
}
]
},
"min_balance": {
"name": "min_balance",
"code": 120,
Expand Down Expand Up @@ -6048,7 +6091,7 @@
"value": null,
"doc": "150 + 7 per 4 bytes of A"
},
"min_avm_version": 11,
"min_avm_version": 12,
"halts": false,
"mode": "any",
"groups": ["Cryptography"],
Expand Down Expand Up @@ -7728,15 +7771,15 @@
},
{
"name": "PayoutsMinBalance",
"doc": "The minimum algo balance an account must have in the agreement round to receive block payouts in the proposal round.",
"doc": "The minimum balance an account must have in the agreement round to receive block payouts in the proposal round.",
"stack_type": "uint64",
"mode": "any",
"value": 21,
"min_avm_version": 11
},
{
"name": "PayoutsMaxBalance",
"doc": "The maximum algo balance an account can have in the agreement round to receive block payouts in the proposal round.",
"doc": "The maximum balance an account can have in the agreement round to receive block payouts in the proposal round.",
"stack_type": "uint64",
"mode": "any",
"value": 22,
Expand Down Expand Up @@ -8179,14 +8222,32 @@
"min_avm_version": 7
}
],
"Mimc Configurations": [
{
"name": "BN254Mp110",
"doc": "MiMC configuration for the BN254 curve with Miyaguchi-Preneel mode, 110 rounds, exponent 5, seed \"seed\"",
"stack_type": null,
"mode": "any",
"value": 0,
"min_avm_version": 11
},
{
"name": "BLS12_381Mp111",
"doc": "MiMC configuration for the BLS12-381 curve with Miyaguchi-Preneel mode, 111 rounds, exponent 5, seed \"seed\"",
"stack_type": null,
"mode": "any",
"value": 1,
"min_avm_version": 11
}
],
"voter_params": [
{
"name": "VoterBalance",
"doc": "Online stake in microalgos",
"stack_type": "uint64",
"mode": "app",
"value": 0,
"min_avm_version": 6
"min_avm_version": 11
},
{
"name": "VoterIncentiveEligible",
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/algo-ts/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@algorandfoundation/algorand-typescript",
"version": "1.0.0-beta.7",
"version": "1.0.0-beta.8",
"description": "This package contains definitions for the types which comprise Algorand TypeScript which can be compiled to run on the Algorand Virtual Machine using the Puya compiler.",
"private": false,
"main": "index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/algo-ts/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export * as gtxn from './gtxn'
export { TransactionType } from './transactions'
export { LogicSig, logicsig } from './logic-sig'
export { TemplateVar } from './template-var'
export { Base64, Ec, Ecdsa, VrfVerify } from './op-types'
export { Base64, Ec, Ecdsa, MimcConfigurations, VrfVerify } from './op-types'
export { compile, CompiledContract, CompiledLogicSig, CompileContractOptions, CompileLogicSigOptions } from './compiled'
export { MutableArray } from './mutable-array'
export { emit } from './arc-28'
24 changes: 19 additions & 5 deletions packages/algo-ts/src/op-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ export enum Ecdsa {
Secp256k1 = 'Secp256k1',
Secp256r1 = 'Secp256r1',
}
export enum MimcConfigurations {
BN254Mp110 = 'BN254Mp110',
BLS12_381Mp111 = 'BLS12_381Mp111',
}
export enum VrfVerify {
VrfAlgorand = 'VrfAlgorand',
}
Expand Down Expand Up @@ -684,7 +688,7 @@ export type ExtractUint64Type = (a: bytes, b: uint64) => uint64
/**
* for (data A, compressed-format signature B, pubkey C) verify the signature of data against the pubkey
* @see Native TEAL opcode: [`falcon_verify`](https://developer.algorand.org/docs/get-details/dapps/avm/teal/opcodes/v10/#falcon_verify)
* Min AVM version: 11
* Min AVM version: 12
*/
export type FalconVerifyType = (a: bytes, b: bytes, c: bytes) => boolean

Expand Down Expand Up @@ -1265,13 +1269,13 @@ export type GlobalType = {
get payoutsPercent(): uint64

/**
* The minimum algo balance an account must have in the agreement round to receive block payouts in the proposal round.
* The minimum balance an account must have in the agreement round to receive block payouts in the proposal round.
* Min AVM version: 11
*/
get payoutsMinBalance(): uint64

/**
* The maximum algo balance an account can have in the agreement round to receive block payouts in the proposal round.
* The maximum balance an account can have in the agreement round to receive block payouts in the proposal round.
* Min AVM version: 11
*/
get payoutsMaxBalance(): uint64
Expand Down Expand Up @@ -2490,6 +2494,15 @@ export type ScratchType = {
store(a: uint64, b: uint64 | bytes): void
}

/**
* MiMC hash of scalars A, using curve and parameters specified by configuration C
* A is a list of concatenated 32 byte big-endian unsigned integer scalars. Fail if A's length is not a multiple of 32 or any element exceeds the curve modulus.
* The MiMC hash function has known collisions since any input which is a multiple of the elliptic curve modulus will hash to the same value. MiMC is thus not a general purpose hash function, but meant to be used in zero knowledge applications to match a zk-circuit implementation.
* @see Native TEAL opcode: [`mimc`](https://developer.algorand.org/docs/get-details/dapps/avm/teal/opcodes/v10/#mimc)
* Min AVM version: 11
*/
export type MimcType = (c: MimcConfigurations, a: bytes) => bytes

/**
* minimum required balance for account A, in microalgos. Required balance is affected by ASA, App, and Box usage. When creating or opting into an app, the minimum balance grows before the app code runs, therefore the increase is visible there. When deleting or closing out, the minimum balance decreases after the app executes. Changes caused by inner transactions or box usage are observable immediately following the opcode effecting the change.
* @param Txn.Accounts offset (or, since v4, an _available_ account address), _available_ application id (or, since v4, a Txn.ForeignApps offset).
Expand Down Expand Up @@ -2580,7 +2593,7 @@ export type SubstringType = (a: bytes, b: uint64, c: uint64) => bytes
/**
* sumhash512 of value A, yields [64]byte
* @see Native TEAL opcode: [`sumhash512`](https://developer.algorand.org/docs/get-details/dapps/avm/teal/opcodes/v10/#sumhash512)
* Min AVM version: 11
* Min AVM version: 12
*/
export type Sumhash512Type = (a: bytes) => bytes

Expand Down Expand Up @@ -2999,7 +3012,7 @@ export type TxnType = {
export type VoterParamsType = {
/**
* Online stake in microalgos
* Min AVM version: 6
* Min AVM version: 11
*/
voterBalance(a: Account | uint64): readonly [uint64, boolean]

Expand Down Expand Up @@ -3068,6 +3081,7 @@ export type OpsNamespace = {
keccak256: Keccak256Type
len: LenType
Scratch: ScratchType
mimc: MimcType
minBalance: MinBalanceType
mulw: MulwType
onlineStake: OnlineStakeType
Expand Down
2 changes: 2 additions & 0 deletions packages/algo-ts/src/op.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
JsonRefType,
Keccak256Type,
LenType,
MimcType,
MulwType,
OnlineStakeType,
OpsNamespace,
Expand Down Expand Up @@ -132,6 +133,7 @@ export const vrfVerify: VrfVerifyType = createFunctionProxy('vrfVerify')
export const onlineStake: OnlineStakeType = createFunctionProxy('onlineStake')
export const falconVerify: FalconVerifyType = createFunctionProxy('falconVerify')
export const sumhash512: Sumhash512Type = createFunctionProxy('sumhash512')
export const mimc: MimcType = createFunctionProxy('mimc')

export const EllipticCurve: EllipticCurveType = createObjectProxy('EllipticCurve')
export const Global: GlobalType = createObjectProxy('Global')
Expand Down
2 changes: 1 addition & 1 deletion scripts/build-op-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ function range(start: number, end: number) {
.fill(0)
.map((_, i) => start + i)
}
export const ENUMS_TO_EXPOSE = new Set(['EC', 'ECDSA', 'vrf_verify', 'base64'])
export const ENUMS_TO_EXPOSE = new Set(['EC', 'ECDSA', 'vrf_verify', 'base64', 'Mimc Configurations'])

const EXCLUDED_OPCODES = new Set([
// low level flow control
Expand Down
12 changes: 12 additions & 0 deletions src/awst_build/op-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4334,6 +4334,18 @@ export const OP_METADATA: Record<string, IntrinsicOpMapping | IntrinsicOpGroupin
},
},
},
mimc: {
type: 'op-mapping',
op: 'mimc',
signatures: [
{
argNames: ['c', 'a'],
immediateArgs: [{ name: 'c', ptypes: [ptypes.mimcConfigurationsPType] }],
stackArgs: [{ name: 'a', ptypes: [ptypes.bytesPType] }],
returnType: ptypes.bytesPType,
},
],
},
minBalance: {
type: 'op-mapping',
op: 'min_balance',
Expand Down
10 changes: 9 additions & 1 deletion src/awst_build/ptypes/op-ptypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,17 @@ export const ecdsaPType = new IntrinsicEnumType({
['Secp256r1', 'Secp256r1'],
],
})
export const mimcConfigurationsPType = new IntrinsicEnumType({
name: 'MimcConfigurations',
module: `${Constants.algoTsPackage}/op-types.d.ts`,
members: [
['BN254Mp110', 'BN254Mp110'],
['BLS12_381Mp111', 'BLS12_381Mp111'],
],
})
export const vrfVerifyPType = new IntrinsicEnumType({
name: 'VrfVerify',
module: `${Constants.algoTsPackage}/op-types.d.ts`,
members: [['VrfAlgorand', 'VrfAlgorand']],
})
export const ALL_OP_ENUMS = [base64PType, ecPType, ecdsaPType, vrfVerifyPType]
export const ALL_OP_ENUMS = [base64PType, ecPType, ecdsaPType, mimcConfigurationsPType, vrfVerifyPType]
7 changes: 3 additions & 4 deletions tests/approvals/avm11.algo.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import type { uint64 } from '@algorandfoundation/algorand-typescript'
import { assert, Bytes, Contract, contract, Global, logicsig, LogicSig, op, Txn } from '@algorandfoundation/algorand-typescript'
import { assert, Bytes, Contract, contract, Global, logicsig, LogicSig, MimcConfigurations, op, Txn } from '@algorandfoundation/algorand-typescript'

@logicsig({ name: 'AVM11SIG', avmVersion: 11 })
export class Avm11Sig extends LogicSig {
program(): uint64 {
return op.sumhash512(Bytes('')).length
return op.mimc(MimcConfigurations.BN254Mp110, Bytes('')).length
}
}

@contract({ name: 'AVM11Contract', avmVersion: 11 })
export class Avm11Contract extends Contract {
testNewOps() {
// Ops
assert(!op.falconVerify(Bytes(), Bytes(), op.bzero(1793)))
assert(op.sumhash512(Bytes()))
assert(op.mimc(MimcConfigurations.BLS12_381Mp111, Bytes()))
assert(op.onlineStake())

// AcctParams
Expand Down
Loading

0 comments on commit b50ab7e

Please sign in to comment.