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

Supporting variants of SHA2 #1957

Draft
wants to merge 29 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
eb5fa81
clarify sha2 or sha3 in examples
querolita Dec 3, 2024
ff313c6
bytes conversion for UInt64
querolita Dec 3, 2024
d040fdc
constants for sha2 variants
querolita Dec 3, 2024
ff1ff4d
preliminary sha2 interface
querolita Dec 3, 2024
b31edda
padding function for short and long sha2
querolita Dec 3, 2024
8847397
generic message schedule function
querolita Dec 4, 2024
a72e52c
infer flag from instanceof generic T to avoid passing is_short
querolita Dec 4, 2024
9c5e988
compression function and auxiliary subroutines from sha256 module
querolita Dec 4, 2024
98be5f2
different parameters for sigma function depending on variant
querolita Dec 4, 2024
3b6c837
generic compression function
querolita Dec 5, 2024
9f001b1
auxiliary functions for reduction modulo 32 64 bits to reduce number …
querolita Dec 5, 2024
1bde951
adapt auxiliary functions for generic case
querolita Dec 5, 2024
62c4ae5
prettify and sigma for 256 and 512
querolita Dec 5, 2024
5f4527a
truncate for 224 and 384 variants
querolita Dec 5, 2024
854cb19
remove length property
querolita Dec 5, 2024
086f927
unit tests for sha2
querolita Dec 5, 2024
4f40f97
undo name change
querolita Dec 5, 2024
9dd0ff6
Merge branch 'main' into feature/eddsa/sha512
querolita Dec 9, 2024
d18716d
Merge branch 'main' into feature/eddsa/sha512
querolita Dec 13, 2024
a9a3668
Merge branch 'main' into feature/eddsa/sha512
querolita Dec 16, 2024
924bb8f
remove unused web3 type import
querolita Dec 16, 2024
0b934e7
pass flag because ts cannot infer types from runtime values
querolita Dec 17, 2024
d2fef76
refactor constants
querolita Dec 18, 2024
47e12da
pass length to functions to improve readability
querolita Dec 18, 2024
06afc51
fix switch syntax
querolita Dec 18, 2024
40482ee
fix aliases for sha3 vs sha2
querolita Dec 18, 2024
b885ddc
update changelog
querolita Dec 18, 2024
86da703
Merge branch 'main' into feature/eddsa/sha512
querolita Dec 19, 2024
a2bc7ec
Merge remote-tracking branch 'origin/feature/eddsa/sha512' into featu…
querolita Dec 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

## [Unreleased](https://github.com/o1-labs/o1js/compare/b857516...HEAD)

### Added

- Gadgets for 224, 384 and 512 bit variants of SHA2 https://github.com/o1-labs/o1js/pull/1957

## [2.2.0](https://github.com/o1-labs/o1js/compare/e1bac02...b857516) - 2024-12-10

### Added
Expand Down
4 changes: 2 additions & 2 deletions flake.lock

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

6 changes: 3 additions & 3 deletions src/examples/zkapps/hashing/hash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@ export class HashStorage extends SmartContract {
this.commitment.set(initialCommitment);
}

@method async SHA256(xs: Bytes32) {
@method async SHA3_256(xs: Bytes32) {
const shaHash = Hash.SHA3_256.hash(xs);
const commitment = Hash.hash(shaHash.toFields());
this.commitment.set(commitment);
}

@method async SHA384(xs: Bytes32) {
@method async SHA3_384(xs: Bytes32) {
const shaHash = Hash.SHA3_384.hash(xs);
const commitment = Hash.hash(shaHash.toFields());
this.commitment.set(commitment);
}

@method async SHA512(xs: Bytes32) {
@method async SHA3_512(xs: Bytes32) {
const shaHash = Hash.SHA3_512.hash(xs);
const commitment = Hash.hash(shaHash.toFields());
this.commitment.set(commitment);
Expand Down
12 changes: 6 additions & 6 deletions src/examples/zkapps/hashing/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,27 +35,27 @@ const initialState =
let currentState;
console.log('Initial State', initialState);

console.log(`Updating commitment from ${initialState} using SHA256 ...`);
console.log(`Updating commitment from ${initialState} using SHA3-256 ...`);
txn = await Mina.transaction(feePayer, async () => {
await contract.SHA256(hashData);
await contract.SHA3_256(hashData);
});
await txn.prove();
await txn.sign([feePayer.key]).send();
currentState = Mina.getAccount(contractAccount).zkapp?.appState?.[0].toString();
console.log(`Current state successfully updated to ${currentState}`);

console.log(`Updating commitment from ${initialState} using SHA384 ...`);
console.log(`Updating commitment from ${initialState} using SHA3-384 ...`);
txn = await Mina.transaction(feePayer, async () => {
await contract.SHA384(hashData);
await contract.SHA3_384(hashData);
});
await txn.prove();
await txn.sign([feePayer.key]).send();
currentState = Mina.getAccount(contractAccount).zkapp?.appState?.[0].toString();
console.log(`Current state successfully updated to ${currentState}`);

console.log(`Updating commitment from ${initialState} using SHA512 ...`);
console.log(`Updating commitment from ${initialState} using SHA3-512 ...`);
txn = await Mina.transaction(feePayer, async () => {
await contract.SHA512(hashData);
await contract.SHA3_512(hashData);
});
await txn.prove();
await txn.sign([feePayer.key]).send();
Expand Down
13 changes: 13 additions & 0 deletions src/lib/provable/crypto/hash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,19 @@ const Hash = {
hash: Gadgets.SHA256.hash,
},

/**
* The SHA2 hash function with an output length of 224 | 256 | 384 | 512 bits.
*/
SHA2: {
/**
* Hashes the given bytes using SHA2.
*
* This is an alias for `Gadgets.SHA2.hash(length,bytes)`.\
* See {@link Gadgets.SHA2.hash} for details and usage examples.
*/
hash: Gadgets.SHA2.hash,
},

/**
* The SHA3 hash function with an output length of 256 bits.
*/
Expand Down
30 changes: 26 additions & 4 deletions src/lib/provable/gadgets/gadgets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
Sum as ForeignFieldSum,
} from './foreign-field.js';
import { divMod32, addMod32, divMod64, addMod64 } from './arithmetic.js';
import { SHA2 } from './sha2.js';
import { SHA256 } from './sha256.js';
import { BLAKE2B } from './blake2b.js';
import { rangeCheck3x12 } from './lookup.js';
Expand Down Expand Up @@ -439,7 +440,7 @@ const Gadgets = {
* Bitwise AND gadget on {@link Field} elements. Equivalent to the [bitwise AND `&` operator in JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_AND).
* The AND gate works by comparing two bits and returning `1` if both bits are `1`, and `0` otherwise.
*
* It can be checked by a double generic gate that verifies the following relationship between the values
* It can be checked by a double generic gate that verifies the following relationship between the values
* below (in the process it also invokes the {@link Gadgets.xor} gadget which will create additional constraints depending on `length`).
*
* The generic gate verifies:\
Expand All @@ -452,7 +453,7 @@ const Gadgets = {
* You can find more details about the implementation in the [Mina book](https://o1-labs.github.io/proof-systems/specs/kimchi.html?highlight=gates#and)
*
* The `length` parameter lets you define how many bits should be compared. `length` is rounded
* to the nearest multiple of 16, `paddedLength = ceil(length / 16) * 16`, and both input values
* to the nearest multiple of 16, `paddedLength = ceil(length / 16) * 16`, and both input values
* are constrained to fit into `paddedLength` bits. The output is guaranteed to have at most `paddedLength` bits as well.
*
* **Note:** Specifying a larger `length` parameter adds additional constraints.
Expand All @@ -476,8 +477,8 @@ const Gadgets = {
* Bitwise OR gadget on {@link Field} elements. Equivalent to the [bitwise OR `|` operator in JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_OR).
* The OR gate works by comparing two bits and returning `1` if at least one bit is `1`, and `0` otherwise.
*
* The `length` parameter lets you define how many bits should be compared. `length` is rounded
* to the nearest multiple of 16, `paddedLength = ceil(length / 16) * 16`, and both input values
* The `length` parameter lets you define how many bits should be compared. `length` is rounded
* to the nearest multiple of 16, `paddedLength = ceil(length / 16) * 16`, and both input values
* are constrained to fit into `paddedLength` bits. The output is guaranteed to have at most `paddedLength` bits as well.
*
* **Note:** Specifying a larger `length` parameter adds additional constraints.
Expand Down Expand Up @@ -973,6 +974,27 @@ const Gadgets = {
*/
SHA256: SHA256,

/**
* Implementation of the [SHA2 hash function.](https://en.wikipedia.org/wiki/SHA-2) Hash function
* with 224 | 256 | 384 | 512 bit output.
*
* Applies the SHA2 hash function to a list of byte-sized elements.
*
* The function accepts {@link Bytes} as the input message, which is a type that represents a static-length list of byte-sized field elements (range-checked using {@link Gadgets.rangeCheck8}).
* Alternatively, you can pass plain `number[]`, `bigint[]` or `Uint8Array` to perform a hash outside provable code.
*
* Produces an output of {@link Bytes} that conforms to the chosen bit length.
*
* @param length - 224 | 256 | 384 | 512 representing the length of the hash.
* @param data - {@link Bytes} representing the message to hash.
*
* ```ts
* let preimage = Bytes.fromString("hello world");
* let digest = Gadgets.SHA2.hash(512, preimage);
* ```
* */
SHA2: SHA2,

/**
* Implementation of the [BLAKE2b hash function.](https://en.wikipedia.org/wiki/BLAKE_(hash_function)#BLAKE2) Hash function with arbitrary length output.
*
Expand Down
Loading
Loading