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

Refactor GenesisUtils: separate primitive type utils #190

Merged
merged 3 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion contracts/identitytreestore/IdentityTreeStore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import {PoseidonUnit2L, PoseidonUnit3L} from "../lib/Poseidon.sol";
import {IState} from "../interfaces/IState.sol";
import {IOnchainCredentialStatusResolver} from "../interfaces/IOnchainCredentialStatusResolver.sol";
import "../interfaces/IRHSStorage.sol";
import {IRHSStorage} from "../interfaces/IRHSStorage.sol";

contract IdentityTreeStore is IOnchainCredentialStatusResolver, IRHSStorage {
/**
Expand All @@ -22,7 +22,7 @@
/**
* @dev Max SMT depth for the CredentialStatus proof
*/
uint256 constant MAX_SMT_DEPTH = 40;

Check warning on line 25 in contracts/identitytreestore/IdentityTreeStore.sol

View workflow job for this annotation

GitHub Actions / solhint

Explicitly mark visibility of state

using ReverseHashLib for ReverseHashLib.Data;

Expand Down Expand Up @@ -56,7 +56,7 @@
*/
function getNode(uint256 key) public view returns (uint256[] memory) {
uint256[] memory preim = _data.getPreimage(key);
require(preim.length > 0, "Node not found");

Check warning on line 59 in contracts/identitytreestore/IdentityTreeStore.sol

View workflow job for this annotation

GitHub Actions / solhint

Use Custom Errors instead of require statements
return preim;
}

Expand All @@ -82,7 +82,7 @@
* @return CredentialStatus
*/
function getRevocationStatusByIdAndState(
uint256 id,

Check warning on line 85 in contracts/identitytreestore/IdentityTreeStore.sol

View workflow job for this annotation

GitHub Actions / solhint

Variable "id" is unused
uint256 state,
uint64 nonce
) external view returns (CredentialStatus memory) {
Expand All @@ -94,7 +94,7 @@
uint64 nonce
) internal view returns (CredentialStatus memory) {
uint256[] memory roots = getNode(state);
require(_nodeType(roots) == NodeType.State, "Invalid state node");

Check warning on line 97 in contracts/identitytreestore/IdentityTreeStore.sol

View workflow job for this annotation

GitHub Actions / solhint

Use Custom Errors instead of require statements

CredentialStatus memory status = CredentialStatus({
issuer: IdentityStateRoots({
Expand Down Expand Up @@ -158,7 +158,7 @@
proof.siblings[i] = children[1];
}
} else {
revert("Invalid node type");

Check warning on line 161 in contracts/identitytreestore/IdentityTreeStore.sol

View workflow job for this annotation

GitHub Actions / solhint

Use Custom Errors instead of revert statements
}
}

Expand Down Expand Up @@ -192,6 +192,6 @@
if (preimage.length == 3) {
return PoseidonUnit3L.poseidon([preimage[0], preimage[1], preimage[2]]);
}
revert("Unsupported length");

Check warning on line 195 in contracts/identitytreestore/IdentityTreeStore.sol

View workflow job for this annotation

GitHub Actions / solhint

Use Custom Errors instead of revert statements
}
}
28 changes: 9 additions & 19 deletions contracts/lib/ClaimBuilder.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.16;

import {BytesLib} from "solidity-bytes-utils/contracts/BytesLib.sol";
import {PrimitiveTypeUtils} from "../lib/PrimitiveTypeUtils.sol";
import {GenesisUtils} from "../lib/GenesisUtils.sol";

Check warning on line 5 in contracts/lib/ClaimBuilder.sol

View workflow job for this annotation

GitHub Actions / solhint

imported name GenesisUtils is not used

library ClaimBuilder {
// ID_POSITION_NONE means ID value not located in claim.
Expand Down Expand Up @@ -65,8 +65,8 @@
uint32 flags;

// Schema
bytes memory cutSchema = BytesLib.slice(
GenesisUtils.uint256ToBytes(GenesisUtils.reverse(c.schemaHash)),
bytes memory cutSchema = PrimitiveTypeUtils.slice(
PrimitiveTypeUtils.uint256ToBytes(PrimitiveTypeUtils.reverse(c.schemaHash)),
0,
16
);
Expand Down Expand Up @@ -125,19 +125,19 @@
require(c.merklizedRoot == 0, "merklizedRoot should be 0 for non merklized claim");
}

bytes memory claim0 = BytesLib.concat(
bytes memory claim0 = PrimitiveTypeUtils.concat(
cutSchema, // 128 bits
abi.encodePacked(reverse(flags)) // 32 bits
abi.encodePacked(PrimitiveTypeUtils.reverse32(flags)) // 32 bits
);

bytes memory claim02 = BytesLib.concat(
abi.encodePacked(reverse(c.version)), // 32 bits
bytes memory claim02 = PrimitiveTypeUtils.concat(
abi.encodePacked(PrimitiveTypeUtils.reverse32(c.version)), // 32 bits
abi.encodePacked(empty64)
);

claim0 = BytesLib.concat(claim0, claim02);
claim0 = PrimitiveTypeUtils.concat(claim0, claim02);

claim[0] = GenesisUtils.reverse(uint256(bytes32(claim0)));
claim[0] = PrimitiveTypeUtils.reverse(uint256(bytes32(claim0)));

// claim[1] was written before

Expand All @@ -154,14 +154,4 @@

return claim;
}

function reverse(uint32 input) internal pure returns (uint32 v) {
v = input;

// swap bytes
v = ((v & 0xFF00FF00) >> 8) | ((v & 0x00FF00FF) << 8);

// swap 2-byte long pairs
v = (v >> 16) | (v << 16);
}
}
89 changes: 11 additions & 78 deletions contracts/lib/GenesisUtils.sol
Original file line number Diff line number Diff line change
@@ -1,59 +1,9 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.16;

import {BytesLib} from "solidity-bytes-utils/contracts/BytesLib.sol";
import {PrimitiveTypeUtils} from "./PrimitiveTypeUtils.sol";

library GenesisUtils {
/**
* @dev uint256ToBytes
*/
function uint256ToBytes(uint256 x) internal pure returns (bytes memory b) {
b = new bytes(32);
assembly {
mstore(add(b, 32), x)
}
}

/**
* @dev reverse
*/
function reverse(uint256 input) internal pure returns (uint256 v) {
v = input;

// swap bytes
v =
((v & 0xFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00) >> 8) |
((v & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) << 8);

// swap 2-byte long pairs
v =
((v & 0xFFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000) >> 16) |
((v & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) << 16);

// swap 4-byte long pairs
v =
((v & 0xFFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000) >> 32) |
((v & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) << 32);

// swap 8-byte long pairs
v =
((v & 0xFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF0000000000000000) >> 64) |
((v & 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) << 64);

// swap 16-byte long pairs
v = (v >> 128) | (v << 128);
}

/**
* @dev reverse uint16
*/
function reverse16(uint16 input) internal pure returns (uint16 v) {
v = input;

// swap bytes
v = (v >> 8) | (v << 8);
}

/**
* @dev sum
*/
Expand All @@ -65,21 +15,11 @@ library GenesisUtils {
}
}

/**
* @dev compareStrings
*/
function compareStrings(string memory a, string memory b) internal pure returns (bool) {
if (bytes(a).length != bytes(b).length) {
return false;
}
return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b))));
}

/**
* @dev isGenesisState
*/
function isGenesisState(uint256 id, uint256 idState) internal pure returns (bool) {
bytes2 idType = bytes2(uint256ToBytes(reverse(id)));
bytes2 idType = bytes2(PrimitiveTypeUtils.uint256ToBytes(PrimitiveTypeUtils.reverse(id)));
uint256 computedId = calcIdFromGenesisState(idType, idState);
return id == computedId;
}
Expand All @@ -91,21 +31,23 @@ library GenesisUtils {
bytes2 idType,
uint256 idState
) internal pure returns (uint256) {
bytes memory userStateB1 = uint256ToBytes(reverse(idState));
bytes memory userStateB1 = PrimitiveTypeUtils.uint256ToBytes(
PrimitiveTypeUtils.reverse(idState)
);

bytes memory cutState = BytesLib.slice(userStateB1, userStateB1.length - 27, 27);
bytes memory cutState = PrimitiveTypeUtils.slice(userStateB1, userStateB1.length - 27, 27);

bytes memory beforeChecksum = BytesLib.concat(abi.encodePacked(idType), cutState);
bytes memory beforeChecksum = PrimitiveTypeUtils.concat(abi.encodePacked(idType), cutState);
require(beforeChecksum.length == 29, "Checksum requires 29 length array");

uint16 checksum = reverse16(sum(beforeChecksum));
uint16 checksum = PrimitiveTypeUtils.reverse16(sum(beforeChecksum));

bytes memory checkSumBytes = abi.encodePacked(checksum);

bytes memory idBytes = BytesLib.concat(beforeChecksum, checkSumBytes);
bytes memory idBytes = PrimitiveTypeUtils.concat(beforeChecksum, checkSumBytes);
require(idBytes.length == 31, "idBytes requires 31 length array");

return reverse(toUint256(idBytes));
return PrimitiveTypeUtils.reverse(PrimitiveTypeUtils.toUint256(idBytes));
}

/**
Expand All @@ -114,15 +56,6 @@ library GenesisUtils {
function calcIdFromEthAddress(bytes2 idType, address caller) internal pure returns (uint256) {
uint256 addr = uint256(uint160(caller));

return calcIdFromGenesisState(idType, reverse(addr));
}

/**
* @dev toUint256
*/
function toUint256(bytes memory _bytes) internal pure returns (uint256 value) {
assembly {
value := mload(add(_bytes, 0x20))
}
return calcIdFromGenesisState(idType, PrimitiveTypeUtils.reverse(addr));
}
}
125 changes: 125 additions & 0 deletions contracts/lib/PrimitiveTypeUtils.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.16;

import {BytesLib} from "solidity-bytes-utils/contracts/BytesLib.sol";

library PrimitiveTypeUtils {
/**
* @dev uint256ToBytes
*/
function uint256ToBytes(uint256 x) internal pure returns (bytes memory b) {
b = new bytes(32);
assembly {
mstore(add(b, 32), x)
}
}

/**
* @dev reverse
*/
function reverse(uint256 input) internal pure returns (uint256 v) {
v = input;

// swap bytes
v =
((v & 0xFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00) >> 8) |
((v & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) << 8);

// swap 2-byte long pairs
v =
((v & 0xFFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000) >> 16) |
((v & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) << 16);

// swap 4-byte long pairs
v =
((v & 0xFFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000) >> 32) |
((v & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) << 32);

// swap 8-byte long pairs
v =
((v & 0xFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF0000000000000000) >> 64) |
((v & 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) << 64);

// swap 16-byte long pairs
v = (v >> 128) | (v << 128);
}

/**
* @dev reverse uint16
*/
function reverse16(uint16 input) internal pure returns (uint16 v) {
v = input;

// swap bytes
v = (v >> 8) | (v << 8);
}

/**
* @dev reverse uint32
*/
function reverse32(uint32 input) internal pure returns (uint32 v) {
v = input;

// swap bytes
v = ((v & 0xFF00FF00) >> 8) | ((v & 0x00FF00FF) << 8);

// swap 2-byte long pairs
v = (v >> 16) | (v << 16);
}

/**
* @dev compareStrings
*/
function compareStrings(string memory a, string memory b) internal pure returns (bool) {
if (bytes(a).length != bytes(b).length) {
return false;
}
return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b))));
}

/**
* @dev toUint256
*/
function toUint256(bytes memory bys) internal pure returns (uint256 value) {
assembly {
value := mload(add(bys, 0x20))
}
}

/**
* @dev bytesToAddress
*/
function bytesToAddress(bytes memory bys) internal pure returns (address addr) {
assembly {
addr := mload(add(bys, 20))
}
}

/**
* @dev int256ToAddress
*/
function int256ToAddress(uint256 input) internal pure returns (address) {
return bytesToAddress(uint256ToBytes(reverse(input)));
}

/**
* @dev concat
*/
function concat(
bytes memory preBytes,
bytes memory postBytes
) internal pure returns (bytes memory) {
return BytesLib.concat(preBytes, postBytes);
}

/**
* @dev slice
*/
function slice(
bytes memory bys,
uint256 start,
uint256 length
) internal pure returns (bytes memory) {
return BytesLib.slice(bys, start, length);
}
}
48 changes: 24 additions & 24 deletions contracts/package-lock.json

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

Loading
Loading