Skip to content

Commit

Permalink
Update benchmark files & circom comparator documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Shigoto-dev19 committed Feb 1, 2024
1 parent 270e18e commit 41d72d9
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 49 deletions.
13 changes: 7 additions & 6 deletions src/benchmarks/benchmark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ import {
} from '../test-utils.js';
import { Hash, Bytes } from 'o1js';

function o1jsSha3_256(input: string) {
// the newly released SHA256 gadget by the o1js team
function o1jsHashReleased(input: string) {
const parsedInput = Bytes.fromString(input);
const sha3Digest = Hash.SHA3_256.hash(parsedInput);
const sha2Digest = Hash.SHA2_256.hash(parsedInput)

return sha3Digest.toHex();
return sha2Digest.toHex();
}

const { mark, compare, run } = bench;
Expand All @@ -28,9 +29,9 @@ run(async () => {
);

await compare(`\nSHA256 Benchmarks => ${iterations} iterations`, iterations, {
o1jsSha3_256: () => o1jsSha3_256(randomInputGenerator() as string),
o1jsSha256Gadgets: () => o1jsHash(randomInputGenerator()),
o1jsSha256Circom: () => o1jsHashCircom(randomInputGenerator()),
o1jsSha256Released: () => o1jsHashReleased(randomInputGenerator() as string),
myO1jsSha256: () => o1jsHash(randomInputGenerator()),
myO1jsSha256Circom: () => o1jsHashCircom(randomInputGenerator()),
nodeSha256: () => nodeHash(randomInputGenerator()),
nobleSha256: () => nobleHash(randomInputGenerator()),
});
Expand Down
13 changes: 7 additions & 6 deletions src/benchmarks/benchmarks.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
### Iterations = 2500

| Hash Function | Operations/sec | Time per Operation | Min Time | Max Time | Variability |
| ----------------- | --------------- | ------------------ | -------- | -------- | ----------- |
| o1jsSha256Circom | 6 ops/sec | 149ms/op ± 1.34% | 105ms | 392ms | ± 1.34% |
| o1jsSha256Gadgets | 334 ops/sec | 2ms/op ± 1.56% | 1ms | 12ms | ± 1.56% |
| nodeSha256 | 331,785 ops/sec | 3μs/op ± 14.46% | 1μs | 515μs | ± 14.46% |
| nobleSha256 | 146,370 ops/sec | 6μs/op ± 28.78% | 1μs | 2ms | ± 28.78% |
| Hash Function | Operations/sec | Average Time/op | Min Time | Max Time | Variability |
|-------------------------|----------------------|------------------| -------- | -------- | ----------- |
| o1jsSha256Released | 267 ops/sec | 3ms/op | - | - | - |
| myO1jsSha256 | 244 ops/sec | 4ms/op | - | - | - |
| myO1jsSha256Circom | 4 ops/sec | 223ms/op | - | - | - |
| nodeSha256 | 309,501 ops/sec | 3μs/op | 2μs | 327μs | ± 8.46% |
| nobleSha256 | 158,127 ops/sec | 6μs/op ± 9.56% | 3μs | 671μs | ± 9.56% |
76 changes: 39 additions & 37 deletions src/benchmarks/comparator/bitwise-functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ export {
*
* @param {UInt32} input - The 32-bit word to be rotated.
* @param {number} r - The number of positions to rotate the bits to the right.
* @returns {Field} A new 32-bit field element representing the result of the right rotation.
* @returns {UInt32} A new 32-bit field element representing the result of the right rotation.
*
* @throws {Error} If the resulting field element exceeds the range of 2^32.
*
* @example
* const inputField = Field(...); // Initialize with a 32-bit field element
* const rotatedResult = rotateRight(inputField, 4); // Performs a right rotation by 4 positions.
* const input = UInt32.from(...); // Initialize with a 32-bit field element
* const rotatedResult = rotateRight(input, 4); // Performs a right rotation by 4 positions.
*/
function rotateRight(input: UInt32, r: number): UInt32 {
const inputBinary = input.value.toBits(32);
Expand All @@ -50,13 +50,13 @@ function rotateRight(input: UInt32, r: number): UInt32 {
* the native o1js function (Gadgets.rightShift(x, r)). It specifically operates on
* hardcoded 32-bit field elements.
*
* @param {Field} input - The 32-bit field element to be shifted.
* @param {UInt32} input - The 32-bit field element to be shifted.
* @param {number} r - The number of positions to shift the bits to the right.
* @returns {Field} A new 32-bit field element representing the result of the right shift.
* @returns {UInt32} A new 32-bit field element representing the result of the right shift.
*
* @example
* const inputField = Field(...); // Initialize with a 32-bit field element
* const shiftedResult = shiftRight(inputField, 4); // Performs a right shift by 4 positions.
* const input = UInt32.from(...); // Initialize with a 32-bit field element
* const shiftedResult = shiftRight(input, 4); // Performs a right shift by 4 positions.
*/
function shiftRight(input: UInt32, r: number): UInt32 {
const inputBinary = input.value.toBits(32);
Expand All @@ -78,16 +78,16 @@ function shiftRight(input: UInt32, r: number): UInt32 {
*
* The choice bitwise operation is defined as: ch(x, y, z) = (x AND y) XOR (-x AND z).
*
* @param {Field} x - The first 32-bit field element.
* @param {Field} y - The second 32-bit field element.
* @param {Field} z - The third 32-bit field element.
* @returns {Field} A new 32-bit field element representing the result of the ch operation.
* @param {UInt32} x - The first 32-bit field element.
* @param {UInt32} y - The second 32-bit field element.
* @param {UInt32} z - The third 32-bit field element.
* @returns {UInt32} A new 32-bit field element representing the result of the ch operation.
*
* @example
* const xField = Field(...); // Initialize with a 32-bit field element
* const yField = Field(...); // Initialize with a 32-bit field element
* const zField = Field(...); // Initialize with a 32-bit field element
* const chResult = ch(xField, yField, zField); // Performs the ch operation.
* const x = UInt32.from(...); // Initialize with a 32-bit field element
* const y = UInt32.from(...); // Initialize with a 32-bit field element
* const z = UInt32.from(...); // Initialize with a 32-bit field element
* const chResult = ch(x, y, z); // Performs the ch operation.
*/
function ch(x: UInt32, y: UInt32, z: UInt32): UInt32 {
const a = x.value.toBits(32).map((bit) => bit.toField());
Expand All @@ -114,10 +114,10 @@ function ch(x: UInt32, y: UInt32, z: UInt32): UInt32 {
* @returns {UInt32} A new 32-bit field element representing the result of the Maj operation.
*
* @example
* const xField = Field(...); // Initialize with a 32-bit field element
* const yField = Field(...); // Initialize with a 32-bit field element
* const zField = Field(...); // Initialize with a 32-bit field element
* const majResult = maj(xField, yField, zField); // Performs the Maj operation.
* const x = UInt32.from(...); // Initialize with a 32-bit field element
* const y = UInt32.from(...); // Initialize with a 32-bit field element
* const z = UInt32.from(...); // Initialize with a 32-bit field element
* const majResult = maj(x, y, z); // Performs the Maj operation.
*/
function maj(x: UInt32, y: UInt32, z: UInt32): UInt32 {
/*
Expand Down Expand Up @@ -145,12 +145,12 @@ function maj(x: UInt32, y: UInt32, z: UInt32): UInt32 {
*
* The Σ0 function is defined as: Σ0(x) = ROTR(2, x) XOR ROTR(13, x) XOR ROTR(22, x).
*
* @param {Field} x - The 32-bit field element to be processed by the Sigma-0 function.
* @returns {Field} A new 32-bit field element representing the result of the Sigma-0 function.
* @param {UInt32} x - The 32-bit field element to be processed by the Sigma-0 function.
* @returns {UInt32} A new 32-bit field element representing the result of the Sigma-0 function.
*
* @example
* const xField = Field(...); // Initialize with a 32-bit field element
* const Σ0Result = SIGMA0(xField); // Calculates the Sigma-0 function.
* const x = UInt32.from(...); // Initialize with a 32-bit field element
* const Σ0Result = SIGMA0(x); // Calculates the Sigma-0 function.
*/
function SIGMA0(x: UInt32): UInt32 {
const rotr2 = rotateRight(x, 2);
Expand All @@ -162,6 +162,7 @@ function SIGMA0(x: UInt32): UInt32 {
rotr22.value,
32
);

return UInt32.from(output);
}

Expand All @@ -170,12 +171,12 @@ function SIGMA0(x: UInt32): UInt32 {
*
* The Σ1 function is defined as: Σ1(x) = ROTR(6, x) XOR ROTR(11, x) XOR ROTR(25, x).
*
* @param {Field} x - The 32-bit field element to be processed by the Σ1 function.
* @returns {Field} A new 32-bit field element representing the result of the Σ1 function.
* @param {UInt32} x - The 32-bit field element to be processed by the Σ1 function.
* @returns {UInt32} A new 32-bit field element representing the result of the Σ1 function.
*
* @example
* const xField = Field(...); // Initialize with a 32-bit field element
* const Σ1Result = SIGMA1(xField); // Calculates the Σ1 function.
* const x = UInt32.from(...); // Initialize with a 32-bit field element
* const Σ1Result = SIGMA1(x); // Calculates the Σ1 function.
*/
function SIGMA1(x: UInt32): UInt32 {
const rotr6 = rotateRight(x, 6);
Expand All @@ -187,6 +188,7 @@ function SIGMA1(x: UInt32): UInt32 {
rotr25.value,
32
);

return UInt32.from(output);
}

Expand All @@ -199,8 +201,8 @@ function SIGMA1(x: UInt32): UInt32 {
* @returns {UInt32} A new 32-bit field element representing the result of the σ0 function.
*
* @example
* const xField = Field(...); // Initialize with a 32-bit field element
* const σ0Result = sigma0(xField); // Calculates the σ0 function.
* const x = UInt32.from(...); // Initialize with a 32-bit field element
* const σ0Result = sigma0(x); // Calculates the σ0 function.
*/
function sigma0(x: UInt32): UInt32 {
const rotr7 = rotateRight(x, 7);
Expand All @@ -222,8 +224,8 @@ function sigma0(x: UInt32): UInt32 {
* @returns {UInt32} A new 32-bit field element representing the result of the σ1 function.
*
* @example
* const xField = Field(...); // Initialize with a 32-bit field element
* const sigma1Result = sigma1(xField); // Calculates the σ1 function.
* const x = UInt32.from(...); // Initialize with a 32-bit field element
* const sigma1Result = sigma1(x); // Calculates the σ1 function.
*/
function sigma1(x: UInt32): UInt32 {
const rotr17 = rotateRight(x, 17);
Expand Down Expand Up @@ -253,14 +255,14 @@ function bitwiseAddition2Mod32(a: UInt32, b: UInt32): UInt32 {
*
* This function iteratively adds multiple field elements using the bitwiseAddition2Mod32 function.
*
* @param {...Field} args - The 32-bit field elements to be added.
* @returns {Field} A new 32-bit field element representing the result of the bitwise addition modulo 2^32.
* @param {...UInt32} args - The 32-bit field elements to be added.
* @returns {UInt32} A new 32-bit field element representing the result of the bitwise addition modulo 2^32.
*
* @example
* const aField = Field(...); // Initialize with a 32-bit field element
* const bField = Field(...); // Initialize with another 32-bit field element
* const cField = Field(...); // Initialize with yet another 32-bit field element
* const result = bitwiseAdditionMod32(aField, bField, cField); // Performs bitwise addition modulo 2^32.
* const a = UInt32.from(...); // Initialize with a 32-bit field element
* const b = UInt32.from(...); // Initialize with another 32-bit field element
* const c = UInt32.from(...); // Initialize with yet another 32-bit field element
* const result = bitwiseAdditionMod32(a, b, c); // Performs bitwise addition modulo 2^32.
*/
function addMod32(...args: UInt32[]): UInt32 {
let sum = UInt32.from(0);
Expand Down

0 comments on commit 41d72d9

Please sign in to comment.