In the SPDZ protocol, parties hold additive shares of a global SPDZ MAC $[\alpha \cdot a]$ on every wire under a single global MAC key $\alpha$. To verify that a reconstructed value $a'$ is correct, each party computes $z_i = a' \cdot \alpha_i - (\alpha \cdot a)_i$, commits to $z_i$, and opens; if the reconstructed $z = \sum z_i \ne 0$, they abort. SPDZ also uses the same commitment scheme in coin-tossing and input-sharing subprotocols.
Fresco’s HashBasedCommitment hashed only the value and the randomness,with no opener identity in the input, allowing a malicious party to replay it. Pre-fix commit method
(source):
1// FILE: tools/commitment/src/main/java/dk/alexandra/fresco/tools/commitment/HashBasedCommitment.java
2// aicis/fresco @ 2dc80dca (vulnerable, pre-PR #433)
3
4public byte[] commit(Drbg rand, byte[] value) {
5 if (commitmentVal != null) {
6 throw new IllegalStateException("Already committed");
7 }
8 // Sample a sufficient amount of random bits
9 byte[] randomness = new byte[DIGEST_LENGTH];
10 rand.nextBytes(randomness);
11 // Construct an array to contain the bytes to hash
12 byte[] openingInfo = new byte[value.length + randomness.length];
13 System.arraycopy(value, 0, openingInfo, 0, value.length);
14 System.arraycopy(randomness, 0, openingInfo, value.length,
15 randomness.length);
16 commitmentVal = digest.digest(openingInfo);
17 return openingInfo;
18}
Each party’s commitment is $c_i = H(v_i \,\|\, r_i)$, with no opener identity in the hash input. Fresco does not implement SPDZ over binary fields, so the characteristic-2 single-MAC-check copy (where a copied $z_1$ gives $z = z_1 + z_1 = 0$) does not apply to it directly. Fresco is instead hit through the same commitment’s use in coin-tossing: a corrupt party copies an honest party’s seed commitment $H(s_i \,\|\, r_i)$ byte-for-byte and later copies the opening $(s_i, r_i)$, so the two identical seeds cancel in the XOR $s = s_1 \oplus \cdots \oplus s_n$. This strips the honest party’s entropy from the tossed coin, making it adversarially predictable and letting the corrupt party pass the batch MAC check on inconsistent values. The fix (PR #433) added the committer’s party ID as the first input to the hash and required the opener to supply a matching ID at open time (source):
1// FILE: tools/commitment/src/main/java/dk/alexandra/fresco/tools/commitment/HashBasedCommitment.java
2// aicis/fresco @ fdada93b (fixed)
3
4public byte[] commit(int myId, Drbg rand, byte[] value) {
5 if (commitmentVal != null) {
6 throw new IllegalStateException("Already committed");
7 }
8 byte[] randomness = new byte[DIGEST_LENGTH];
9 rand.nextBytes(randomness);
10 // Party ID is now the first ID_LENGTH bytes of the hashed input.
11 byte[] openingInfo = new byte[ID_LENGTH + value.length + randomness.length];
12 System.arraycopy(integerToBytes(myId), 0, openingInfo, 0, ID_LENGTH);
13 System.arraycopy(value, 0, openingInfo, ID_LENGTH, value.length);
14 System.arraycopy(randomness, 0, openingInfo, value.length + ID_LENGTH,
15 randomness.length);
16 commitmentVal = digest.digest(openingInfo);
17 return openingInfo;
18}