Skip to content

Commit

Permalink
add rust CI
Browse files Browse the repository at this point in the history
  • Loading branch information
clabby committed Jan 5, 2024
1 parent 4fbf93d commit c712ef2
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 162 deletions.
68 changes: 68 additions & 0 deletions .github/workflows/rust-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: Rust CI
on: [push]

env:
CARGO_TERM_COLOR: always

jobs:
init:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust nightly toolchain
uses: dtolnay/rust-toolchain@nightly
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
- name: install just
uses: taiki-e/install-action@just
- name: generate testdata
run: |
just testdata
- uses: bissolli/gh-action-persist-workspace@v1
with:
action: persist
cargo-tests:
needs: [init]
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: bissolli/gh-action-persist-workspace@v1
with:
action: retrieve
- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
- name: fuzz test
run: cargo run --release -- -m 100 -t 4 --diff-count 50000
cargo-lint:
needs: [init]
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: bissolli/gh-action-persist-workspace@v1
with:
action: retrieve
- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
- name: cargo fmt
run: cargo fmt --all -- --check
- name: cargo clippy
run: cargo clippy --workspace --all --locked -- -D warnings
cargo-build:
needs: [init]
runs-on: ubuntu-latest
timeout-minutes: 20
continue-on-error: true
steps:
- uses: bissolli/gh-action-persist-workspace@v1
with:
action: retrieve
- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
- name: build
id: build
run: cargo build --workspace --all --locked
7 changes: 1 addition & 6 deletions .github/workflows/sol-test.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
name: sol-test

on: workflow_dispatch
on: [push]

env:
FOUNDRY_PROFILE: ci
Expand All @@ -16,23 +15,19 @@ jobs:
- uses: actions/checkout@v4
with:
submodules: recursive

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly

- name: Run Forge build
run: |
forge --version
forge build --sizes
id: build

- name: Check formatting
run: |
forge fmt --check
id: fmt

- name: Run Forge tests
run: |
forge test -vvv
Expand Down
4 changes: 2 additions & 2 deletions contracts/StatefulSponge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ contract StatefulSponge {
function squeeze() external returns (bytes32 hash_) {
// Squeeze the sponge.
hash_ = Lib_Keccak256.get_hash(state);

// Reset the state matrix.
delete state;
}
Expand All @@ -54,7 +54,7 @@ contract StatefulSponge {
function _pad(bytes calldata _data) internal pure returns (bytes memory padded_) {
assembly {
padded_ := mload(0x40)

let len := _data.length
let offset := _data.offset

Expand Down
237 changes: 116 additions & 121 deletions contracts/lib/LK.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,137 +5,132 @@ pragma solidity >0.5.0;
// https://github.com/firefly/wallet/blob/master/source/libs/ethers/src/keccak256.c

library Lib_Keccak256 {
struct CTX {
uint64[25] A;
}

function get_round_constant(uint round) internal pure returns (uint64) {
uint64 result = 0;
uint8 roundInfo = uint8(0x7421587966164852535d4f3f26350c0e5579211f705e1a01 >> (round*8));
result |= (uint64(roundInfo) << (63-6)) & (1 << 63);
result |= (uint64(roundInfo) << (31-5)) & (1 << 31);
result |= (uint64(roundInfo) << (15-4)) & (1 << 15);
result |= (uint64(roundInfo) << (7-3)) & (1 << 7);
result |= (uint64(roundInfo) << (3-2)) & (1 << 3);
result |= (uint64(roundInfo) << (1-1)) & (1 << 1);
result |= (uint64(roundInfo) << (0-0)) & (1 << 0);
return result;
}
struct CTX {
uint64[25] A;
}

function keccak_theta_rho_pi(CTX memory c) internal pure {
uint64 C0 = c.A[0] ^ c.A[5] ^ c.A[10] ^ c.A[15] ^ c.A[20];
uint64 C1 = c.A[1] ^ c.A[6] ^ c.A[11] ^ c.A[16] ^ c.A[21];
uint64 C2 = c.A[2] ^ c.A[7] ^ c.A[12] ^ c.A[17] ^ c.A[22];
uint64 C3 = c.A[3] ^ c.A[8] ^ c.A[13] ^ c.A[18] ^ c.A[23];
uint64 C4 = c.A[4] ^ c.A[9] ^ c.A[14] ^ c.A[19] ^ c.A[24];
uint64 D0 = (C1 << 1) ^ (C1 >> 63) ^ C4;
uint64 D1 = (C2 << 1) ^ (C2 >> 63) ^ C0;
uint64 D2 = (C3 << 1) ^ (C3 >> 63) ^ C1;
uint64 D3 = (C4 << 1) ^ (C4 >> 63) ^ C2;
uint64 D4 = (C0 << 1) ^ (C0 >> 63) ^ C3;
c.A[0] ^= D0;
uint64 A1 = ((c.A[1] ^ D1) << 1) ^ ((c.A[1] ^ D1) >> (64-1)); //
c.A[1] = ((c.A[6] ^ D1) << 44) ^ ((c.A[6] ^ D1) >> (64-44)); // 6, 1, 44, D1
c.A[6] = ((c.A[9] ^ D4) << 20) ^ ((c.A[9] ^ D4) >> (64-20)); // 9, 6, 20, D4
c.A[9] = ((c.A[22] ^ D2) << 61) ^ ((c.A[22] ^ D2) >> (64-61)); // 22, 9, 61, D2
c.A[22] = ((c.A[14] ^ D4) << 39) ^ ((c.A[14] ^ D4) >> (64-39)); // 14, 22, 39, D4
c.A[14] = ((c.A[20] ^ D0) << 18) ^ ((c.A[20] ^ D0) >> (64-18)); // 20, 14, 18, D0
c.A[20] = ((c.A[2] ^ D2) << 62) ^ ((c.A[2] ^ D2) >> (64-62)); // 2, 20, 62, D2
c.A[2] = ((c.A[12] ^ D2) << 43) ^ ((c.A[12] ^ D2) >> (64-43)); // 12, 2, 43, D2
c.A[12] = ((c.A[13] ^ D3) << 25) ^ ((c.A[13] ^ D3) >> (64-25)); // 13, 12, 25, D3
c.A[13] = ((c.A[19] ^ D4) << 8) ^ ((c.A[19] ^ D4) >> (64-8)); // 19, 13, 8, D4
c.A[19] = ((c.A[23] ^ D3) << 56) ^ ((c.A[23] ^ D3) >> (64-56)); // 23, 19, 56, D3
c.A[23] = ((c.A[15] ^ D0) << 41) ^ ((c.A[15] ^ D0) >> (64-41)); // 15, 23, 41, D0
c.A[15] = ((c.A[4] ^ D4) << 27) ^ ((c.A[4] ^ D4) >> (64-27)); // 4, 15, 27, D4
c.A[4] = ((c.A[24] ^ D4) << 14) ^ ((c.A[24] ^ D4) >> (64-14)); // 24, 4, 14, D4
c.A[24] = ((c.A[21] ^ D1) << 2) ^ ((c.A[21] ^ D1) >> (64-2)); // 21, 24, 2, D1
c.A[21] = ((c.A[8] ^ D3) << 55) ^ ((c.A[8] ^ D3) >> (64-55)); // 8, 21, 55, D3
c.A[8] = ((c.A[16] ^ D1) << 45) ^ ((c.A[16] ^ D1) >> (64-45)); // 16, 8, 45, D1
c.A[16] = ((c.A[5] ^ D0) << 36) ^ ((c.A[5] ^ D0) >> (64-36)); // 5, 16, 36, D0
c.A[5] = ((c.A[3] ^ D3) << 28) ^ ((c.A[3] ^ D3) >> (64-28)); // 3, 5, 28, D3
c.A[3] = ((c.A[18] ^ D3) << 21) ^ ((c.A[18] ^ D3) >> (64-21)); // 18, 3, 21, D3
c.A[18] = ((c.A[17] ^ D2) << 15) ^ ((c.A[17] ^ D2) >> (64-15)); // 17, 18, 15, D2
c.A[17] = ((c.A[11] ^ D1) << 10) ^ ((c.A[11] ^ D1) >> (64-10)); // 11, 17, 10, D1
c.A[11] = ((c.A[7] ^ D2) << 6) ^ ((c.A[7] ^ D2) >> (64-6)); // 7, 11, 6, D2
c.A[7] = ((c.A[10] ^ D0) << 3) ^ ((c.A[10] ^ D0) >> (64-3)); // 10, 7, 3, D0
c.A[10] = A1;
}
function get_round_constant(uint256 round) internal pure returns (uint64) {
uint64 result = 0;
uint8 roundInfo = uint8(0x7421587966164852535d4f3f26350c0e5579211f705e1a01 >> (round * 8));
result |= (uint64(roundInfo) << (63 - 6)) & (1 << 63);
result |= (uint64(roundInfo) << (31 - 5)) & (1 << 31);
result |= (uint64(roundInfo) << (15 - 4)) & (1 << 15);
result |= (uint64(roundInfo) << (7 - 3)) & (1 << 7);
result |= (uint64(roundInfo) << (3 - 2)) & (1 << 3);
result |= (uint64(roundInfo) << (1 - 1)) & (1 << 1);
result |= (uint64(roundInfo) << (0 - 0)) & (1 << 0);
return result;
}

function keccak_chi(CTX memory c) internal pure {
uint i;
uint64 A0;
uint64 A1;
uint64 A2;
uint64 A3;
uint64 A4;
for (i = 0; i < 25; i+=5) {
A0 = c.A[0 + i];
A1 = c.A[1 + i];
A2 = c.A[2 + i];
A3 = c.A[3 + i];
A4 = c.A[4 + i];
c.A[0 + i] ^= ~A1 & A2;
c.A[1 + i] ^= ~A2 & A3;
c.A[2 + i] ^= ~A3 & A4;
c.A[3 + i] ^= ~A4 & A0;
c.A[4 + i] ^= ~A0 & A1;
function keccak_theta_rho_pi(CTX memory c) internal pure {
uint64 C0 = c.A[0] ^ c.A[5] ^ c.A[10] ^ c.A[15] ^ c.A[20];
uint64 C1 = c.A[1] ^ c.A[6] ^ c.A[11] ^ c.A[16] ^ c.A[21];
uint64 C2 = c.A[2] ^ c.A[7] ^ c.A[12] ^ c.A[17] ^ c.A[22];
uint64 C3 = c.A[3] ^ c.A[8] ^ c.A[13] ^ c.A[18] ^ c.A[23];
uint64 C4 = c.A[4] ^ c.A[9] ^ c.A[14] ^ c.A[19] ^ c.A[24];
uint64 D0 = (C1 << 1) ^ (C1 >> 63) ^ C4;
uint64 D1 = (C2 << 1) ^ (C2 >> 63) ^ C0;
uint64 D2 = (C3 << 1) ^ (C3 >> 63) ^ C1;
uint64 D3 = (C4 << 1) ^ (C4 >> 63) ^ C2;
uint64 D4 = (C0 << 1) ^ (C0 >> 63) ^ C3;
c.A[0] ^= D0;
uint64 A1 = ((c.A[1] ^ D1) << 1) ^ ((c.A[1] ^ D1) >> (64 - 1)); //
c.A[1] = ((c.A[6] ^ D1) << 44) ^ ((c.A[6] ^ D1) >> (64 - 44));
// 6, 1, 44, D1
c.A[6] = ((c.A[9] ^ D4) << 20) ^ ((c.A[9] ^ D4) >> (64 - 20)); // 9, 6, 20, D4
c.A[9] = ((c.A[22] ^ D2) << 61) ^ ((c.A[22] ^ D2) >> (64 - 61)); // 22, 9, 61, D2
c.A[22] = ((c.A[14] ^ D4) << 39) ^ ((c.A[14] ^ D4) >> (64 - 39)); // 14, 22, 39, D4
c.A[14] = ((c.A[20] ^ D0) << 18) ^ ((c.A[20] ^ D0) >> (64 - 18)); // 20, 14, 18, D0
c.A[20] = ((c.A[2] ^ D2) << 62) ^ ((c.A[2] ^ D2) >> (64 - 62)); // 2, 20, 62, D2
c.A[2] = ((c.A[12] ^ D2) << 43) ^ ((c.A[12] ^ D2) >> (64 - 43)); // 12, 2, 43, D2
c.A[12] = ((c.A[13] ^ D3) << 25) ^ ((c.A[13] ^ D3) >> (64 - 25)); // 13, 12, 25, D3
c.A[13] = ((c.A[19] ^ D4) << 8) ^ ((c.A[19] ^ D4) >> (64 - 8)); // 19, 13, 8, D4
c.A[19] = ((c.A[23] ^ D3) << 56) ^ ((c.A[23] ^ D3) >> (64 - 56)); // 23, 19, 56, D3
c.A[23] = ((c.A[15] ^ D0) << 41) ^ ((c.A[15] ^ D0) >> (64 - 41)); // 15, 23, 41, D0
c.A[15] = ((c.A[4] ^ D4) << 27) ^ ((c.A[4] ^ D4) >> (64 - 27)); // 4, 15, 27, D4
c.A[4] = ((c.A[24] ^ D4) << 14) ^ ((c.A[24] ^ D4) >> (64 - 14)); // 24, 4, 14, D4
c.A[24] = ((c.A[21] ^ D1) << 2) ^ ((c.A[21] ^ D1) >> (64 - 2)); // 21, 24, 2, D1
c.A[21] = ((c.A[8] ^ D3) << 55) ^ ((c.A[8] ^ D3) >> (64 - 55)); // 8, 21, 55, D3
c.A[8] = ((c.A[16] ^ D1) << 45) ^ ((c.A[16] ^ D1) >> (64 - 45)); // 16, 8, 45, D1
c.A[16] = ((c.A[5] ^ D0) << 36) ^ ((c.A[5] ^ D0) >> (64 - 36)); // 5, 16, 36, D0
c.A[5] = ((c.A[3] ^ D3) << 28) ^ ((c.A[3] ^ D3) >> (64 - 28)); // 3, 5, 28, D3
c.A[3] = ((c.A[18] ^ D3) << 21) ^ ((c.A[18] ^ D3) >> (64 - 21)); // 18, 3, 21, D3
c.A[18] = ((c.A[17] ^ D2) << 15) ^ ((c.A[17] ^ D2) >> (64 - 15)); // 17, 18, 15, D2
c.A[17] = ((c.A[11] ^ D1) << 10) ^ ((c.A[11] ^ D1) >> (64 - 10)); // 11, 17, 10, D1
c.A[11] = ((c.A[7] ^ D2) << 6) ^ ((c.A[7] ^ D2) >> (64 - 6)); // 7, 11, 6, D2
c.A[7] = ((c.A[10] ^ D0) << 3) ^ ((c.A[10] ^ D0) >> (64 - 3)); // 10, 7, 3, D0
c.A[10] = A1;
}
}

function keccak_init(CTX memory c) internal pure {
// is this needed?
uint i;
for (i = 0; i < 25; i++) {
c.A[i] = 0;
function keccak_chi(CTX memory c) internal pure {
uint256 i;
uint64 A0;
uint64 A1;
uint64 A2;
uint64 A3;
uint64 A4;
for (i = 0; i < 25; i += 5) {
A0 = c.A[0 + i];
A1 = c.A[1 + i];
A2 = c.A[2 + i];
A3 = c.A[3 + i];
A4 = c.A[4 + i];
c.A[0 + i] ^= ~A1 & A2;
c.A[1 + i] ^= ~A2 & A3;
c.A[2 + i] ^= ~A3 & A4;
c.A[3 + i] ^= ~A4 & A0;
c.A[4 + i] ^= ~A0 & A1;
}
}
}

function sha3_xor_input(CTX memory c, bytes memory dat) internal pure {
for (uint i = 0; i < 17; i++) {
uint bo = i*8;
c.A[i] ^= uint64(uint8(dat[bo+7])) << 56 |
uint64(uint8(dat[bo+6])) << 48 |
uint64(uint8(dat[bo+5])) << 40 |
uint64(uint8(dat[bo+4])) << 32 |
uint64(uint8(dat[bo+3])) << 24 |
uint64(uint8(dat[bo+2])) << 16 |
uint64(uint8(dat[bo+1])) << 8 |
uint64(uint8(dat[bo+0])) << 0;
function keccak_init(CTX memory c) internal pure {
// is this needed?
uint256 i;
for (i = 0; i < 25; i++) {
c.A[i] = 0;
}
}
}

function sha3_permutation(CTX memory c) internal pure {
uint round;
for (round = 0; round < 24; round++) {
keccak_theta_rho_pi(c);
// if (round == 1) {
// assembly {
// log0(add(c, 0x20), mul(0x20, 25))
// }
// }
keccak_chi(c);
// if (round == 1) {
// assembly {
// log0(add(c, 0x20), mul(0x20, 25))
// }
// }
// keccak_iota
c.A[0] ^= get_round_constant(round);
function sha3_xor_input(CTX memory c, bytes memory dat) internal pure {
for (uint256 i = 0; i < 17; i++) {
uint256 bo = i * 8;
c.A[i] ^= uint64(uint8(dat[bo + 7])) << 56 | uint64(uint8(dat[bo + 6])) << 48
| uint64(uint8(dat[bo + 5])) << 40 | uint64(uint8(dat[bo + 4])) << 32 | uint64(uint8(dat[bo + 3])) << 24
| uint64(uint8(dat[bo + 2])) << 16 | uint64(uint8(dat[bo + 1])) << 8 | uint64(uint8(dat[bo + 0])) << 0;
}
}
}

// https://stackoverflow.com/questions/2182002/convert-big-endian-to-little-endian-in-c-without-using-provided-func
function flip(uint64 val) internal pure returns (uint64) {
val = ((val << 8) & 0xFF00FF00FF00FF00 ) | ((val >> 8) & 0x00FF00FF00FF00FF );
val = ((val << 16) & 0xFFFF0000FFFF0000 ) | ((val >> 16) & 0x0000FFFF0000FFFF );
return (val << 32) | (val >> 32);
}
function sha3_permutation(CTX memory c) internal pure {
uint256 round;
for (round = 0; round < 24; round++) {
keccak_theta_rho_pi(c);
// if (round == 1) {
// assembly {
// log0(add(c, 0x20), mul(0x20, 25))
// }
// }
keccak_chi(c);
// if (round == 1) {
// assembly {
// log0(add(c, 0x20), mul(0x20, 25))
// }
// }
// keccak_iota
c.A[0] ^= get_round_constant(round);
}
}

function get_hash(CTX memory c) internal pure returns (bytes32) {
return bytes32((uint256(flip(c.A[0])) << 192) |
(uint256(flip(c.A[1])) << 128) |
(uint256(flip(c.A[2])) << 64) |
(uint256(flip(c.A[3])) << 0));
}
// https://stackoverflow.com/questions/2182002/convert-big-endian-to-little-endian-in-c-without-using-provided-func
function flip(uint64 val) internal pure returns (uint64) {
val = ((val << 8) & 0xFF00FF00FF00FF00) | ((val >> 8) & 0x00FF00FF00FF00FF);
val = ((val << 16) & 0xFFFF0000FFFF0000) | ((val >> 16) & 0x0000FFFF0000FFFF);
return (val << 32) | (val >> 32);
}

function get_hash(CTX memory c) internal pure returns (bytes32) {
return bytes32(
(uint256(flip(c.A[0])) << 192) | (uint256(flip(c.A[1])) << 128) | (uint256(flip(c.A[2])) << 64)
| (uint256(flip(c.A[3])) << 0)
);
}
}
Loading

0 comments on commit c712ef2

Please sign in to comment.