What’s New in o1js: January 2024

Ethereum compatibility with Keccak, ECDSA, bitwise operations, and foreign field arithmetic

image

Our commitment to our vibrant developer community led us here. Ethereum compatibility has been a resounding ask. Keccak, integral for hashing addresses, transactions, and blocks in Ethereum, and ECDSA, crucial for signing and verifying messages, are now natively supported in o1js.

Used together, Keccak hashing and ECDSA signature verification enable a wide range of use cases, such as proof of ownership of an Ethereum address for exclusive chat or private voting. These substantial updates to o1js greatly expand the capabilities of what’s possible in the realm of zkApps on the Mina Protocol.

o1js Highlights

First, we released Bitwise Operations to make the process of implementing new cryptographic primitives in o1js easier and more efficient. By having access to fast and provable binary operations, you can use bitwise operations as building blocks for more advanced cryptographic algorithms, such as SHA, RSA, and more.

Foreign Field Arithmetic extends o1js capabilities to handle operations in fields different from its native proof system. Foreign fields facilitate the implementation of cryptographic functions that are compatible with external systems, making it possible for applications to work with external cryptographic systems.

With the foundations in place, we built on that work to implement Keccak and ECDSA.

  • Keccak is a flexible cryptographic hash function that provides more security than traditional SHA hash algorithms. You can use Keccak to verify Ethereum transactions and blocks in o1js, bridging a crucial gap in blockchain interoperability. Keccak enhances the security of applications and provides a flexible and powerful tool so you can implement a range of cryptographic solutions, from creating unique digital fingerprints to ensuring data integrity.
  • ECDSA is a cryptographic algorithm that is used to sign and verify messages for enhanced security. While ECDSA has various applications, a key advantage is its role in Ethereum signature verification. This integration equips you with the tools required for generating and verifying Ethereum signatures, effectively linking zkApps with the Ethereum ecosystem.

Added

  • Non-native elliptic curve operations exposed through createForeignCurve() class factory. (0.15.1, #1007)
  • ECDSA signature verification exposed through createEcdsa() class factory. (0.15.1, #1240, #1007, #1307)
    - For an example, see ./src/examples/crypto/ecdsa.
  • Keccak/SHA3 hash function exposed on Keccak namespace. (0.15.1, #1291)
  • Hash namespace which holds all hash functions. (0.15.1, #999)
    - Bytes, provable type to hold a byte array, which serves as input and output for Keccak variants.
    - UInt8, provable type to hold a single byte, which is constrained to be in the 0 to 255 range.
  • Gadgets.rotate32() for rotation over 32 bit values. (0.15.1, #1259)
  • Gadgets.leftShift32() for left shift over 32 bit values. (0.15.1, #1259)
  • Gadgets.divMod32() division modulo 2^32 that returns the remainder and quotient of the operation (0.15.1, #1259)
  • Gadgets.rangeCheck32() range check for 32 bit values. (0.15.1, #1259)
  • Gadgets.addMod32() addition modulo 2^32. (0.15.1, #1259)
  • Expose new bitwise gadgets on UInt32 and UInt64. (0.15.1, #1259)
    -bitwise XOR via {UInt32, UInt64}.xor()
    -bitwise NOT via {UInt32, UInt64}.not()
    -bitwise ROTATE via {UInt32, UInt64}.rotate()
    -bitwise LEFTSHIFT via {UInt32, UInt64}.leftShift()
    -bitwise RIGHTSHIFT via {UInt32, UInt64}.rightShift()
    -bitwise AND via {UInt32, UInt64}.and()
  • Example for using actions to store a map data structure. (0.15.1, #1300)
  • Provable.constraintSystem()and{ZkProgram,SmartContract}.analyzeMethods() return a summary() method to return a summary of the constraints used by a method. (0.15.1, #1007)
  • Foreign field arithmetic exposed through the createForeignField() class factory. (0.15.0, #985)
  • Crypto namespace which exposes elliptic curve and finite field arithmetic on BigInts, as well as example curve parameters. (0.15.0, #1240)
  • Gadgets.ForeignField.assertMul() for efficiently constraining products of sums in non-native arithmetic. (0.15.0, #1262)
  • Unconstrained for safely maintaining unconstrained values in provable code. (0.15.0, #1262)
  • Gadgets.rangeCheck8() to assert that a value fits in 8 bits. (0.15.0, #1288)
  • Provable non-native field arithmetic:
  • Gadgets.ForeignField.{add, sub, sumchain}() for addition and subtraction. (0.14.2, #1220)
  • Gadgets.ForeignField.{mul, inv, div}() for multiplication and division. (0.14.2, #1223)
  • Comprehensive internal testing of constraint system layouts generated by new gadgets. (0.14.2, #1241, #1220)
  • Gadgets.not(), new provable method to support bitwise not. (0.14.1, #1198)
  • Gadgets.leftShift() / Gadgets.rightShift(), new provable methods to support bitwise shifting. (0.14.1, #1194)
  • Gadgets.and(), new provable method to support bitwise and. (0.14.1, #1193)
  • Gadgets.multiRangeCheck() and Gadgets.compactMultiRangeCheck(), two building blocks for non-native arithmetic with BigInts of size up to 264 bits. (0.14.1, #1216)

Changed

  • Change precondition APIs to use “require” instead of “assert” as the verb, to distinguish them from provable assertions. @LuffySama-Dev
    - this.x.getAndAssertEquals() is now this.x.getAndRequireEquals() (0.15.0, #1263) @LuffySama-Dev
    - this.x.assertEquals(x) is now this.x.requireEquals(x). (0.15.0, #1263) @LuffySama-Dev
    - this.account.x.getAndAssertEquals(x) is now this.account.x.requireEquals(x). (0.15.0, #1265) @LuffySama-Dev
    - this.account.x.assertBetween() is now this.account.x.requireBetween(). (0.15.0, #1265) @LuffySama-Dev
    - this.network.x.getAndAssertEquals() is now this.network.x.getAndRequireEquals(). (0.15.0, #1265) @LuffySama-Dev
  • Provable.constraintSystem() and {ZkProgram,SmartContract}.analyzeMethods() return a print() method for pretty-printing the constraint system. (0.15.0, #1240)
  • Lightnet namespace API updates with added listAcquiredKeyPairs() method. (0.14.2, #1256)
  • Expose raw provable methods of a ZkProgram on zkProgram.rawMethods. (0.14.2, #1241)
  • Reduce number of constraints needed by rotate(), leftShift(), and rightShift() gadgets. (0.14.2, #1201)

Fixed

  • Fix bug in Hash.hash() which always resulted in an error. (0.15.2, #1346)
  • Fix stack overflows when calling provable methods with large inputs. (0.15.1, #1334)
  • Fix Local.setProofsEnabled() which would not get picked up by deploy(). (0.15.1, #1330)
  • Remove usage of private class fields in core types like Field, for better type compatibility between different o1js versions. (0.15.1, #1319)
  • Fix missing recursive verification of proofs in smart contracts. (0.15.0, #1302)
  • Add a parameter to checkZkappTransaction for block length to check for transaction inclusion. This fixes a case where Transaction.wait() only checked the latest block, which led to an error once the transaction was included in a block that was not the latest. (0.14.2, #1239)
  • Removed array reversal of fetched actions, since they are returned in the correct order. (0.14.1, #1258)

Breaking changes

  • Rename Gadgets.rotate() to Gadgets.rotate64() to better reflect the amount of bits the gadget operates on. (0.15.1, #1259)
  • Rename Gadgets.{leftShift(), rightShift()} to Gadgets.{leftShift64(), rightShift64()} to better reflect the amount of bits the gadget operates on. (0.15.1, #1259)
  • ZkProgram.compile() now returns the verification key and its hash, to be consistent with SmartContract.compile(). (0.15.0, #1292) @rpanic
  • Change return signature of ZkProgram.analyzeMethods() to be a keyed object. (0.14.2, #1223)

zkApp CLI Updates

Added

  • Possibility to configure the lightnet Mina processes logging level. (0.16.0, #536)
  • Lightnet sub-commands implementation (explorer). (0.15.2, #521)
  • Lightnet sub-commands implementation (logs). (0.15.1, #520)

Changed

  • Updates the GitHub Pages UI scaffold deploy flow configuration in next.config.js to be compatible with the current version of NextJS. (0.16.0, #534)
  • Explorer links for deployment and interaction transactions. (0.14.1, #516)

Fixed

  • Fix to allow a deployment to GitHub Pages using the npm run deploy command in a NextJS UI project. (0.16.0, #534)

Shout outs

A strong community helps us build and deliver better software faster. We are always grateful for community members who contribute, engage, explore, and share knowledge.

We appreciate quality contributions from highly motivated community members. Thanks for earning extra points for making updates to the CHANGELOG.

  • Special thanks to @LuffySama-Dev for making more than a few significant contributions to the o1js codebase and the docs.
  • Thanks to @rpanic for fixes.

Small fixes are also appreciated. Thanks to @Ursulafe for fixing several typos in the codebase doc comments and Violet-Bora-Lee for contributing to docs. It’s better together.

Shout out to DFST for posting about faster compile times on Twitter/X:

The latest update to the o1js library has revolutionized the way we compile recursive proofs ZkPrograms. Imagine this: a staggering FIFTEEN MILLION TIMES faster compilation in a serverless environment!

And posting results on Mina Protocol Discord in the #zkapps-questions channel.

Are you building zkApps with o1js? Help us celebrate you. Tag @o1_labs on Twitter/X when you share your work.

To stay up to date

Follow the official o1Labs @o1_labs on Twitter/X.

To participate

Mina Protocol Discord is the most popular place where Mina enthusiasts and technical contributors gather to share knowledge.

Join us in these zkApps channels:

To contribute

To learn how you can help us improve the functionality and user experience, which in turn helps you build better projects, see: