Coverage Summary for Class: Keccak256 (co.rsk.crypto)
Class |
Method, %
|
Line, %
|
Keccak256 |
81.8%
(9/11)
|
50%
(12/24)
|
Keccak256$MockitoMock$1899471238 |
Keccak256$MockitoMock$1899471238$auxiliary$gLqtIzw7 |
Keccak256$MockitoMock$1899471238$auxiliary$KWby5mu3 |
Keccak256$MockitoMock$1899471238$auxiliary$MIRUzn3B |
Keccak256$MockitoMock$1899471238$auxiliary$pFmJntyc |
Keccak256$MockitoMock$1899471238$auxiliary$Q2h5zxpa |
Keccak256$MockitoMock$1899471238$auxiliary$vvkhVpPg |
Keccak256$MockitoMock$1899471238$auxiliary$zX41BlXP |
Total |
81.8%
(9/11)
|
50%
(12/24)
|
1 /*
2 * This file is part of RskJ
3 * Copyright (C) 2017 RSK Labs Ltd.
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 package co.rsk.crypto;
20
21 import co.rsk.bitcoinj.core.Utils;
22 import com.google.common.primitives.Ints;
23 import org.ethereum.rpc.TypeConverter;
24 import org.ethereum.util.ByteUtil;
25
26 import java.io.Serializable;
27 import java.util.Arrays;
28
29 import static com.google.common.base.Preconditions.checkArgument;
30
31 /**
32 * A Keccak256 just wraps a byte[] so that equals and hashcode work correctly, allowing it to be used as keys in a
33 * map. It also checks that the length is correct and provides a bit more type safety.
34 */
35 public class Keccak256 implements Serializable, Comparable<Keccak256> {
36 public static final int HASH_LEN = 32;
37 public static final Keccak256 ZERO_HASH = new Keccak256(new byte[HASH_LEN]);
38
39 private final byte[] bytes;
40
41 public Keccak256(byte[] rawHashBytes) {
42 checkArgument(rawHashBytes.length == HASH_LEN);
43 this.bytes = rawHashBytes;
44 }
45
46 public Keccak256(String hexString) {
47 checkArgument(hexString.length() == 2*HASH_LEN);
48 this.bytes = Utils.HEX.decode(hexString);
49 }
50
51 public String toJsonString() {
52 return TypeConverter.toUnformattedJsonHex(this.bytes);
53 }
54
55 public String toHexString() {
56 return ByteUtil.toHexString(bytes);
57 }
58
59 @Override
60 public boolean equals(Object o) {
61 return this == o || o != null && getClass() == o.getClass() && Arrays.equals(bytes, ((Keccak256) o).bytes);
62 }
63
64 /**
65 * Returns the last four bytes of the wrapped hash. This should be unique enough to be a suitable hash code even for
66 * blocks, where the goal is to try and get the first bytes to be zeros (i.e. the value as a big integer lower
67 * than the target value).
68 */
69 @Override
70 public int hashCode() {
71 // Use the last 4 bytes, not the first 4 which are often zeros in Bitcoin.
72 return Ints.fromBytes(bytes[28], bytes[29], bytes[30], bytes[31]);
73 }
74
75 /**
76 * @return a DEBUG representation of the hash, mainly used for logging.
77 */
78 @Override
79 public String toString() {
80 return toHexString();
81 }
82
83 /**
84 * Returns the internal byte array, without defensively copying. Therefore do NOT modify the returned array.
85 */
86 public byte[] getBytes() {
87 return bytes;
88 }
89
90 /**
91 * Returns an identical Sha3Hash with a copy of the the internal byte array.
92 */
93 public Keccak256 copy() {
94 return new Keccak256(ByteUtil.cloneBytes(bytes));
95 }
96
97 @Override
98 public int compareTo(Keccak256 o) {
99 for (int i = HASH_LEN - 1; i >= 0; i--) {
100 final int thisByte = this.bytes[i] & 0xff;
101 final int otherByte = o.bytes[i] & 0xff;
102 if (thisByte > otherByte) {
103 return 1;
104 }
105
106 if (thisByte < otherByte) {
107 return -1;
108 }
109 }
110 return 0;
111 }
112 }