diff --git a/pipeline.developer-examples/pipeline.developer-examples.fodid/README.md b/pipeline.developer-examples/pipeline.developer-examples.fodid/README.md index e7cb93bf7..62cd57a7b 100644 --- a/pipeline.developer-examples/pipeline.developer-examples.fodid/README.md +++ b/pipeline.developer-examples/pipeline.developer-examples.fodid/README.md @@ -6,7 +6,7 @@ This module holds the developer examples for the 51Did package | Program | What it shows | | --- | --- | -| `Main` | Reads a 51Did offline. Builds a sample identifier in process, parses it back with `FodId` and shows that the value is stable while the envelope changes on every issue. Needs no cloud access. | +| `Main` | Reads a 51Did offline. Builds a sample identifier in process, parses it back with `FodId` and shows that the match key is stable while the envelope changes on every issue. Needs no cloud access. | | `CreatorContextDemoServer` | Serves a small web page that creates a 51Did in the browser, verifies it from the browser, and redeems the encrypted creator context result on this server with `DidClient`, which is the only place the licence key lives. | ## Creator context diff --git a/pipeline.developer-examples/pipeline.developer-examples.fodid/src/main/java/pipeline/developerexamples/fodid/Main.java b/pipeline.developer-examples/pipeline.developer-examples.fodid/src/main/java/pipeline/developerexamples/fodid/Main.java index 1e98446fa..7e82805eb 100644 --- a/pipeline.developer-examples/pipeline.developer-examples.fodid/src/main/java/pipeline/developerexamples/fodid/Main.java +++ b/pipeline.developer-examples/pipeline.developer-examples.fodid/src/main/java/pipeline/developerexamples/fodid/Main.java @@ -37,8 +37,8 @@ * back with {@link FodId} and prints the three payload fields. *
* It also demonstrates the headline use case: a 51Did is re-issued fresh on
- * every call (the envelope, hence the base64, changes), but the value (the
- * Hash) is stable. Compare values, never envelopes.
+ * every call (the envelope, hence the base64, changes), but the match key
+ * is stable. Compare match keys, never envelopes.
*/
public class Main {
@@ -62,28 +62,29 @@ public void run() throws Exception {
System.out.println(" Flags : 0x"
+ Integer.toHexString(fodId.getFlags()));
System.out.println(" LicenseId : " + fodId.getLicenseId());
- System.out.println(" Hash : " + toHex(fodId.getHash()));
+ System.out.println(" Match key : " + toHex(fodId.getMatchKey()));
System.out.println(" Verifies : "
+ fodId.verify(crypto.publicKeyPem()));
- // Issue the SAME payload again: a separate envelope, same value.
+ // Issue the SAME payload again: a separate envelope, same match
+ // key.
FodId reissued = FodId.fromBase64(issue(creator, payload));
boolean sameEnvelope =
fodId.asBase64().equals(reissued.asBase64());
- boolean sameValue =
- Arrays.equals(fodId.getHash(), reissued.getHash());
+ boolean sameMatchKey =
+ Arrays.equals(fodId.getMatchKey(), reissued.getMatchKey());
System.out.println();
System.out.println("Same payload, re-issued:");
System.out.println(" Same envelope (base64) : " + sameEnvelope);
- System.out.println(" Same value (Hash) : " + sameValue);
+ System.out.println(" Same match key : " + sameMatchKey);
- // The reader's whole purpose: the value is the stable, comparable
- // part while the envelope is not.
- if (sameEnvelope || !sameValue) {
+ // The reader's whole purpose: the match key is the stable,
+ // comparable part while the envelope is not.
+ if (sameEnvelope || !sameMatchKey) {
throw new IllegalStateException(
- "Expected a different envelope but the same value "
- + "across reissues.");
+ "Expected a different envelope but the same match "
+ + "key across reissues.");
}
}
@@ -99,7 +100,7 @@ private String issue(Creator creator, byte[] payload)
/**
* A canonical 37-byte Probabilistic payload: flags 0x00, License Id
- * 0x12345678 (little-endian) and a 32-byte value 0x20..0x3F.
+ * 0x12345678 (little-endian) and a 32-byte match key 0x20..0x3F.
*/
private byte[] samplePayload() {
byte[] payload = new byte[FodId.PAYLOAD_LENGTH];
diff --git a/pipeline.developer-examples/pipeline.developer-examples.fodid/src/test/java/pipeline/developerexamples/fodid/ExampleTests.java b/pipeline.developer-examples/pipeline.developer-examples.fodid/src/test/java/pipeline/developerexamples/fodid/ExampleTests.java
index 9451e81fc..7f37bc31e 100644
--- a/pipeline.developer-examples/pipeline.developer-examples.fodid/src/test/java/pipeline/developerexamples/fodid/ExampleTests.java
+++ b/pipeline.developer-examples/pipeline.developer-examples.fodid/src/test/java/pipeline/developerexamples/fodid/ExampleTests.java
@@ -72,8 +72,8 @@ public void init() throws Exception {
/**
* The 51Did example is fully offline, so unlike the cloud examples it must
* complete without throwing. {@code run()} also self-checks the
- * value-stable / envelope-changes invariant and throws if it does not
- * hold.
+ * invariant that the match key is stable while the envelope changes,
+ * and throws if it does not hold.
*/
@Test
public void FodId_Example_Test() throws Exception {
@@ -241,7 +241,7 @@ private static String keyList(Crypto crypto) {
/**
* A canonical 37-byte Probabilistic payload: flags 0x00, License Id
- * 0x12345678 (little-endian) and a 32-byte value 0x20..0x3F.
+ * 0x12345678 (little-endian) and a 32-byte match key 0x20..0x3F.
*/
private static byte[] samplePayload() {
byte[] payload = new byte[FodId.PAYLOAD_LENGTH];
diff --git a/pipeline.did/README.md b/pipeline.did/README.md
index be047f66a..21b9f18f1 100644
--- a/pipeline.did/README.md
+++ b/pipeline.did/README.md
@@ -13,26 +13,27 @@ A 51Did is described at three levels, and the wording is deliberate.
the version, domain, date, payload and signature. It changes byte-for-byte
every time the cloud issues one, even for the same inputs, because the date
and signature change on each call.
-- The **value** is the stable, comparable part of the payload after the Flags
- and License Id: a 32-byte SHA-256 for Probabilistic and HashedEmail
+- The **match key** is the stable, comparable part of the payload after the
+ Flags and License Id, a 32-byte SHA-256 for Probabilistic and HashedEmail
identifiers, or 16 GUID bytes for Random. Two 51Dids for the same inputs
- share the same value even though their envelopes differ.
+ share the same match key even though their envelopes differ.
-**Comparing two 51Dids means comparing their values, never their envelopes.**
+**Comparing two 51Dids means comparing their match keys, never their
+envelopes.**
## Payload layout
-The header is shared by every identifier type; bits 6-7 of Flags select the
-type and the length of the value that follows.
+The header is shared by every identifier type. Bits 6-7 of Flags select the
+type and the length of the match key that follows.
| Offset | Length | Field | Type |
|-------:|-------:|------------|-------------------------------------------------|
| 0 | 1 | Flags | uint8: bits 0-2 usage, bits 6-7 identifier type |
| 1 | 4 | LicenseId | uint32 (little-endian) |
-| 5 | 16/32 | Value | SHA-256 (Probabilistic, HashedEmail) or GUID (Random) |
+| 5 | 16/32 | Match key | SHA-256 (Probabilistic, HashedEmail) or GUID (Random) |
| after | any | Context | Optional creator context section, readable only by 51Degrees |
-| Bits 7-6 | `IdType` | Value length | Minimum payload |
+| Bits 7-6 | `IdType` | Match key length | Minimum payload |
|---------:|-----------------|-------------:|----------------:|
| `00` | `PROBABILISTIC` | 32 | 37 |
| `01` | `RANDOM` | 16 | 21 |
@@ -172,7 +173,7 @@ FodId fodId = FodId.fromBase64(base64FromCloudService);
int flags = fodId.getFlags();
IdType type = fodId.getType(); // PROBABILISTIC / RANDOM / HASHED_EMAIL
long licenseId = fodId.getLicenseId();
-byte[] hash = fodId.getHash(); // SHA-256 or GUID bytes, see type
+byte[] matchKey = fodId.getMatchKey(); // SHA-256 or GUID bytes, see type
// Delegated OWID-level fields and operations.
String domain = fodId.getDomain();
@@ -189,11 +190,13 @@ FodId a = FodId.fromBase64(idprobglobalA);
FodId b = FodId.fromBase64(idprobglobalB);
// The envelope (date, signature, base64) differs across reissues.
-// The value inside the payload is stable - this is what you compare:
-boolean sameValue = java.util.Arrays.equals(a.getHash(), b.getHash());
+// The match key inside the payload is stable - this is what you compare:
+boolean sameMatchKey = java.util.Arrays.equals(a.getMatchKey(), b.getMatchKey());
```
-Use `getHash()` as the cache / dedup key.
+Use `getMatchKey()` as the cache / dedup key. `getHash()` remains as a
+deprecated alias of `getMatchKey()`, returning the same bytes, and will be
+removed in a future release.
## Verifying on your server
@@ -342,4 +345,4 @@ signed envelopes there is no longer a copy made inside it.
- **No creation of new 51Dids.** This is a reader and a verifier; new 51Dids
are issued by the 51Degrees cloud / on-premise hashing engines.
- **No upper bound on a payload.** The cloud owns the shape of anything past
- the value, and this package does not second-guess it.
+ the match key, and this package does not second-guess it.
diff --git a/pipeline.did/pom.xml b/pipeline.did/pom.xml
index 76f140c31..4598505c4 100644
--- a/pipeline.did/pom.xml
+++ b/pipeline.did/pom.xml
@@ -37,8 +37,8 @@
- * Payload layout. The header (offsets 0-4) is shared by every identifier type;
- * bits 6-7 of Flags select the {@link IdType} and the length of the value that
- * follows:
+ * Payload layout. The header (offsets 0-4) is shared by every identifier type.
+ * Bits 6-7 of Flags select the {@link IdType} and the length of the match key
+ * that follows:
*
* Reading and verifying are two separate steps. {@link #tryFromBase64(String)}
@@ -95,10 +96,10 @@ public final class FodId {
/** Byte length of the License Id field. */
public static final int LICENSE_ID_LENGTH = 4;
- /** Byte offset of the value (Hash) field within the payload. */
+ /** Byte offset of the match key field within the payload. */
public static final int HASH_OFFSET = 5;
- /** Byte length of the SHA-256 value. */
+ /** Byte length of the match key field (SHA-256). */
public static final int HASH_LENGTH = 32;
/**
@@ -107,7 +108,7 @@ public final class FodId {
*/
public static final int HEADER_LENGTH = HASH_OFFSET;
- /** Byte length of the GUID value carried by Random identifiers. */
+ /** Byte length of the GUID match key carried by Random identifiers. */
public static final int GUID_LENGTH = 16;
/**
@@ -118,7 +119,7 @@ public final class FodId {
/**
* Minimum byte length of a Probabilistic or HashedEmail 51Did payload
- * (Flags + License Id + Hash). Random payloads are shorter - see
+ * (Flags + License Id + match key). Random payloads are shorter - see
* {@link #RANDOM_PAYLOAD_LENGTH}.
*/
public static final int PAYLOAD_LENGTH = HASH_OFFSET + HASH_LENGTH;
@@ -132,18 +133,18 @@ public final class FodId {
private final Owid owid;
private final int flags;
private final long licenseId;
- private final byte[] hash;
+ private final byte[] matchKey;
/**
* Built only by {@link #read(Owid)} once the payload has passed the
* 51Did rules, so an instance never exists for a payload that failed
* them.
*/
- private FodId(Owid owid, int flags, long licenseId, byte[] hash) {
+ private FodId(Owid owid, int flags, long licenseId, byte[] matchKey) {
this.owid = owid;
this.flags = flags;
this.licenseId = licenseId;
- this.hash = hash;
+ this.matchKey = matchKey;
}
// ----- Reading without throwing -----
@@ -205,7 +206,8 @@ private static FodIdParseResult read(OwidParseResult envelope) {
* The rules are lower bounds only. The header must be present before the
* type can be read, and the type then sets the least the payload can
* hold. Anything longer is accepted as it stands, because the bytes past
- * the value are a creator context section whose shape the cloud judges.
+ * the match key are a creator context section whose shape the cloud
+ * judges.
*/
private static FodIdParseResult read(Owid owid) {
byte[] payload = owid.getPayload();
@@ -213,21 +215,22 @@ private static FodIdParseResult read(Owid owid) {
return FodIdParseResult.failed(FodIdParseStatus.PAYLOAD_TOO_SHORT);
}
int flags = payload[FLAGS_OFFSET] & 0xFF;
- int valueLength;
+ int matchKeyLength;
switch (IdType.fromFlags(flags)) {
case RANDOM:
- valueLength = GUID_LENGTH;
+ matchKeyLength = GUID_LENGTH;
break;
case RESERVED:
// Not yet assigned, so read best-effort. The header fields
- // are unpacked and whatever follows is exposed as the value.
- valueLength = payload.length - HEADER_LENGTH;
+ // are unpacked and whatever follows is exposed as the
+ // match key.
+ matchKeyLength = payload.length - HEADER_LENGTH;
break;
default:
- valueLength = HASH_LENGTH;
+ matchKeyLength = HASH_LENGTH;
break;
}
- if (payload.length < HEADER_LENGTH + valueLength) {
+ if (payload.length < HEADER_LENGTH + matchKeyLength) {
return FodIdParseResult.failed(
FodIdParseStatus.INVALID_TYPE_PAYLOAD_LENGTH);
}
@@ -238,12 +241,13 @@ private static FodIdParseResult read(Owid owid) {
| ((payload[LICENSE_ID_OFFSET + 1] & 0xFFL) << 8)
| ((payload[LICENSE_ID_OFFSET + 2] & 0xFFL) << 16)
| ((payload[LICENSE_ID_OFFSET + 3] & 0xFFL) << 24);
- // The value is copied out so that mutating the array a caller gets
- // back from getHash() can never reach the envelope's own bytes.
- byte[] hash = Arrays.copyOfRange(
- payload, HASH_OFFSET, HASH_OFFSET + valueLength);
+ // The match key is copied out so that mutating the array a caller
+ // gets back from getMatchKey() can never reach the envelope's own
+ // bytes.
+ byte[] matchKey = Arrays.copyOfRange(
+ payload, HASH_OFFSET, HASH_OFFSET + matchKeyLength);
return FodIdParseResult.parsed(
- new FodId(owid, flags, licenseId, hash));
+ new FodId(owid, flags, licenseId, matchKey));
}
// ----- Reading with exceptions -----
@@ -396,15 +400,31 @@ public long getLicenseId() {
}
/**
- * Returns the value bytes from the payload (a 32-byte SHA-256 for
+ * Returns the match key from the payload (a 32-byte SHA-256 for
* Probabilistic and HashedEmail identifiers, or 16 GUID bytes for Random).
- * This is the stable, comparable part of the envelope - use it as the
- * cache / dedup key.
+ * The match key is the stable, comparable part of the envelope. Two
+ * 51Dids for the same inputs share the same match key even though their
+ * envelopes (date, signature) differ on every issue, so use the match
+ * key as the cache / dedup key.
*
- * @return a defensive copy of the value bytes
+ * @return a defensive copy of the match key bytes
*/
+ public byte[] getMatchKey() {
+ return matchKey.clone();
+ }
+
+ /**
+ * Deprecated alias for {@link #getMatchKey()}. The stable, comparable
+ * part of a 51Did is now called the match key, mirroring the Model Terms
+ * for Marketing vocabulary. This alias will be removed in a future
+ * release.
+ *
+ * @return the same bytes as {@link #getMatchKey()}
+ * @deprecated renamed to {@link #getMatchKey()}
+ */
+ @Deprecated
public byte[] getHash() {
- return hash.clone();
+ return getMatchKey();
}
/** @return the OWID version. */
diff --git a/pipeline.did/src/main/java/fiftyone/pipeline/did/FodIdParseStatus.java b/pipeline.did/src/main/java/fiftyone/pipeline/did/FodIdParseStatus.java
index a9f998561..447f1c07a 100644
--- a/pipeline.did/src/main/java/fiftyone/pipeline/did/FodIdParseStatus.java
+++ b/pipeline.did/src/main/java/fiftyone/pipeline/did/FodIdParseStatus.java
@@ -110,8 +110,8 @@ public enum FodIdParseStatus {
* The envelope read and the header names a type, but the payload is
* shorter than the minimum for that type. Random needs the header plus
* 16 GUID bytes, and Probabilistic and HashedEmail need the header plus
- * a 32 byte hash. A longer payload is never refused here, because
- * anything past the value is a creator context section whose lengths
+ * a 32 byte match key. A longer payload is never refused here, because
+ * anything past the match key is a creator context section whose lengths
* belong to the cloud.
*/
INVALID_TYPE_PAYLOAD_LENGTH;
diff --git a/pipeline.did/src/main/java/fiftyone/pipeline/did/package-info.java b/pipeline.did/src/main/java/fiftyone/pipeline/did/package-info.java
index 74d564420..fbe521ffa 100644
--- a/pipeline.did/src/main/java/fiftyone/pipeline/did/package-info.java
+++ b/pipeline.did/src/main/java/fiftyone/pipeline/did/package-info.java
@@ -30,11 +30,11 @@
* {@link fiftyone.pipeline.did.FodIdParseResult} instead of throwing, whose
* {@link fiftyone.pipeline.did.FodIdParseStatus} names why an input is not
* a 51Did, and the {@code from} readers make the same read and throw. A
- * 51Did exposes the three payload fields (Flags, License Id and the value
- * Hash) and the identifier {@link fiftyone.pipeline.did.IdType}, and
+ * 51Did exposes the three payload fields (Flags, License Id and the match
+ * key) and the identifier {@link fiftyone.pipeline.did.IdType}, and
* delegates OWID-level concerns to the envelope it holds. Reading never
- * checks the signature. Compare 51Dids by their value ({@code getHash()}),
- * never by their envelopes.
+ * checks the signature. Compare 51Dids by their match key
+ * ({@code getMatchKey()}), never by their envelopes.
*
* {@link fiftyone.pipeline.did.DidClient} is what a server uses against the
* 51Degrees cloud: it fetches and holds the published signing keys, verifies
diff --git a/pipeline.did/src/test/java/fiftyone/pipeline/did/FodIdParseTests.java b/pipeline.did/src/test/java/fiftyone/pipeline/did/FodIdParseTests.java
index 61b3f758f..9335549bc 100644
--- a/pipeline.did/src/test/java/fiftyone/pipeline/did/FodIdParseTests.java
+++ b/pipeline.did/src/test/java/fiftyone/pipeline/did/FodIdParseTests.java
@@ -34,7 +34,7 @@
import java.util.Arrays;
import static fiftyone.pipeline.did.FodIdTestFactory.CANONICAL_FLAGS;
-import static fiftyone.pipeline.did.FodIdTestFactory.CANONICAL_HASH;
+import static fiftyone.pipeline.did.FodIdTestFactory.CANONICAL_MATCH_KEY;
import static fiftyone.pipeline.did.FodIdTestFactory.CANONICAL_LICENSE_ID;
import static fiftyone.pipeline.did.FodIdTestFactory.TEST_DOMAIN;
import static fiftyone.pipeline.did.FodIdTestFactory.canonicalPayload;
@@ -77,7 +77,7 @@ public void tryFromBase64_ValidIdentifier_ParsedWithValue()
FodId fodId = assertParsed(result);
assertEquals(CANONICAL_FLAGS, fodId.getFlags());
assertEquals(CANONICAL_LICENSE_ID, fodId.getLicenseId());
- assertArrayEquals(CANONICAL_HASH, fodId.getHash());
+ assertArrayEquals(CANONICAL_MATCH_KEY, fodId.getMatchKey());
assertEquals(TEST_DOMAIN, fodId.getDomain());
}
@@ -93,7 +93,7 @@ public void tryFromBase64_UrlSafeUnpaddedWithWhitespace_Parsed()
FodId.tryFromBase64(" " + urlSafe + "\r\n"));
assertArrayEquals(fromUrlSafe.asByteArray(), fromSpaced.asByteArray());
- assertArrayEquals(CANONICAL_HASH, fromUrlSafe.getHash());
+ assertArrayEquals(CANONICAL_MATCH_KEY, fromUrlSafe.getMatchKey());
}
@Test
@@ -103,7 +103,7 @@ public void tryFromByteArray_ValidIdentifier_ParsedWithValue()
FodId fodId = assertParsed(FodId.tryFromByteArray(bytes));
- assertArrayEquals(CANONICAL_HASH, fodId.getHash());
+ assertArrayEquals(CANONICAL_MATCH_KEY, fodId.getMatchKey());
assertArrayEquals(bytes, fodId.asByteArray());
}
@@ -126,15 +126,15 @@ public void tryFromBase64_LongerSelfHostedDomain_Parsed()
@Test
public void tryFromBase64_LongerContextSection_Parsed() throws Exception {
- // A payload longer than the value carries a creator context section
+ // A payload longer than the match key carries a creator context section
// whose shape belongs to the cloud, so an older reader accepts it
- // and exposes it as the payload beyond the value.
+ // and exposes it as the payload beyond the match key.
byte[] payload = canonicalPayloadWithSection(512);
String base64 = factory.signedOwidAt(payload, DATE).asBase64();
FodId fodId = assertParsed(FodId.tryFromBase64(base64));
- assertArrayEquals(CANONICAL_HASH, fodId.getHash());
+ assertArrayEquals(CANONICAL_MATCH_KEY, fodId.getMatchKey());
assertArrayEquals(payload, fodId.getPayload());
assertTrue(fodId.verify(factory.publicPem));
}
@@ -150,7 +150,7 @@ public void tryFromByteArray_MuchLongerPayload_NotRejectedForLength()
FodId fodId = assertParsed(FodId.tryFromByteArray(bytes));
assertEquals(payload.length, fodId.getPayload().length);
- assertArrayEquals(CANONICAL_HASH, fodId.getHash());
+ assertArrayEquals(CANONICAL_MATCH_KEY, fodId.getMatchKey());
}
byte[] random = Arrays.copyOf(canonicalRandomPayload(), 700);
assertParsed(FodId.tryFromByteArray(
@@ -183,7 +183,7 @@ public void tryFromBase64_ReservedHeaderOnly_ParsedBestEffort()
factory.signedOwidAt(payload, DATE).asBase64()));
assertEquals(IdType.RESERVED, fodId.getType());
- assertEquals(0, fodId.getHash().length);
+ assertEquals(0, fodId.getMatchKey().length);
}
// ----- 51Did payload rules -----
diff --git a/pipeline.did/src/test/java/fiftyone/pipeline/did/FodIdTestFactory.java b/pipeline.did/src/test/java/fiftyone/pipeline/did/FodIdTestFactory.java
index f02d6c5d3..e92f6e77e 100644
--- a/pipeline.did/src/test/java/fiftyone/pipeline/did/FodIdTestFactory.java
+++ b/pipeline.did/src/test/java/fiftyone/pipeline/did/FodIdTestFactory.java
@@ -53,7 +53,7 @@ final class FodIdTestFactory {
static final long CANONICAL_LICENSE_ID = 0x12345678L;
- static final byte[] CANONICAL_HASH = canonicalHash();
+ static final byte[] CANONICAL_MATCH_KEY = canonicalMatchKey();
static final Instant DATE_ORIGIN = Instant.parse("2020-01-01T00:00:00Z");
@@ -73,12 +73,12 @@ final class FodIdTestFactory {
this.creator = Creator.create(TEST_DOMAIN, crypto);
}
- private static byte[] canonicalHash() {
- byte[] hash = new byte[FodId.HASH_LENGTH];
- for (int i = 0; i < hash.length; i++) {
- hash[i] = (byte) (0x20 + i);
+ private static byte[] canonicalMatchKey() {
+ byte[] matchKey = new byte[FodId.HASH_LENGTH];
+ for (int i = 0; i < matchKey.length; i++) {
+ matchKey[i] = (byte) (0x20 + i);
}
- return hash;
+ return matchKey;
}
static byte[] canonicalPayload() {
@@ -86,7 +86,8 @@ static byte[] canonicalPayload() {
payload[FodId.FLAGS_OFFSET] = (byte) CANONICAL_FLAGS;
writeCanonicalLicenseId(payload);
System.arraycopy(
- CANONICAL_HASH, 0, payload, FodId.HASH_OFFSET, FodId.HASH_LENGTH);
+ CANONICAL_MATCH_KEY, 0, payload,
+ FodId.HASH_OFFSET, FodId.HASH_LENGTH);
return payload;
}
diff --git a/pipeline.did/src/test/java/fiftyone/pipeline/did/FodIdTests.java b/pipeline.did/src/test/java/fiftyone/pipeline/did/FodIdTests.java
index b78a276ee..9afdce4c9 100644
--- a/pipeline.did/src/test/java/fiftyone/pipeline/did/FodIdTests.java
+++ b/pipeline.did/src/test/java/fiftyone/pipeline/did/FodIdTests.java
@@ -35,7 +35,7 @@
import java.util.Base64;
import static fiftyone.pipeline.did.FodIdTestFactory.CANONICAL_FLAGS;
-import static fiftyone.pipeline.did.FodIdTestFactory.CANONICAL_HASH;
+import static fiftyone.pipeline.did.FodIdTestFactory.CANONICAL_MATCH_KEY;
import static fiftyone.pipeline.did.FodIdTestFactory.CANONICAL_LICENSE_ID;
import static fiftyone.pipeline.did.FodIdTestFactory.TEST_DOMAIN;
import static fiftyone.pipeline.did.FodIdTestFactory.canonicalPayload;
@@ -85,7 +85,7 @@ public void constructor_FromBase64_UnpacksAllThreeFields() throws Exception {
assertEquals(CANONICAL_FLAGS, fodId.getFlags());
assertEquals(CANONICAL_LICENSE_ID, fodId.getLicenseId());
- assertArrayEquals(CANONICAL_HASH, fodId.getHash());
+ assertArrayEquals(CANONICAL_MATCH_KEY, fodId.getMatchKey());
assertEquals(TEST_DOMAIN, fodId.getDomain());
}
@@ -98,7 +98,7 @@ public void constructor_FromBytes_UnpacksAllThreeFields() throws Exception {
assertEquals(CANONICAL_FLAGS, fodId.getFlags());
assertEquals(CANONICAL_LICENSE_ID, fodId.getLicenseId());
- assertArrayEquals(CANONICAL_HASH, fodId.getHash());
+ assertArrayEquals(CANONICAL_MATCH_KEY, fodId.getMatchKey());
assertEquals(TEST_DOMAIN, fodId.getDomain());
}
@@ -110,7 +110,7 @@ public void constructor_FromOwid_UnpacksAllThreeFields() throws Exception {
assertEquals(CANONICAL_FLAGS, fodId.getFlags());
assertEquals(CANONICAL_LICENSE_ID, fodId.getLicenseId());
- assertArrayEquals(CANONICAL_HASH, fodId.getHash());
+ assertArrayEquals(CANONICAL_MATCH_KEY, fodId.getMatchKey());
assertEquals(owid.getDomain(), fodId.getDomain());
assertEquals(owid.getDate(), fodId.getDate());
assertEquals(owid.getVersion(), fodId.getVersion());
@@ -185,16 +185,28 @@ public void flags_AllBitsSet_Exposed() throws Exception {
}
@Test
- public void hash_IsDefensiveCopy() throws Exception {
+ public void matchKey_IsDefensiveCopy() throws Exception {
FodId fodId = FodId.fromBase64(factory.signedOwidBase64(canonicalPayload()));
- byte[] hash = fodId.getHash();
- hash[0] = 0x00;
- hash[FodId.HASH_LENGTH - 1] = 0x00;
+ byte[] matchKey = fodId.getMatchKey();
+ matchKey[0] = 0x00;
+ matchKey[FodId.HASH_LENGTH - 1] = 0x00;
- // Neither the underlying payload nor a fresh getHash() is affected.
- assertEquals(CANONICAL_HASH[0], fodId.getPayload()[FodId.HASH_OFFSET]);
- assertArrayEquals(CANONICAL_HASH, fodId.getHash());
+ // Neither the underlying payload nor a fresh getMatchKey() is affected.
+ assertEquals(
+ CANONICAL_MATCH_KEY[0], fodId.getPayload()[FodId.HASH_OFFSET]);
+ assertArrayEquals(CANONICAL_MATCH_KEY, fodId.getMatchKey());
+ }
+
+ @Test
+ @SuppressWarnings("deprecation")
+ public void getHash_DeprecatedAlias_ReturnsMatchKey() throws Exception {
+ // getHash() stays as a deprecated alias so that callers written
+ // against the earlier name keep compiling and get the same bytes.
+ FodId fodId = FodId.fromBase64(factory.signedOwidBase64(canonicalPayload()));
+
+ assertArrayEquals(fodId.getMatchKey(), fodId.getHash());
+ assertArrayEquals(CANONICAL_MATCH_KEY, fodId.getHash());
}
@Test
@@ -238,8 +250,8 @@ public void constructor_PayloadLargerThanSpec_UsesFirst37Bytes() throws Exceptio
assertEquals(CANONICAL_FLAGS, fodId.getFlags());
assertEquals(CANONICAL_LICENSE_ID, fodId.getLicenseId());
- assertArrayEquals(CANONICAL_HASH, fodId.getHash());
- assertEquals(FodId.HASH_LENGTH, fodId.getHash().length);
+ assertArrayEquals(CANONICAL_MATCH_KEY, fodId.getMatchKey());
+ assertEquals(FodId.HASH_LENGTH, fodId.getMatchKey().length);
}
@Test
@@ -262,7 +274,7 @@ public void constructor_LongContextSectionAndLongDomain_Parses()
for (FodId fodId : new FodId[] { fromBytes, fromBase64, fromOwid }) {
assertEquals(longDomain, fodId.getDomain());
assertEquals(CANONICAL_FLAGS, fodId.getFlags());
- assertArrayEquals(CANONICAL_HASH, fodId.getHash());
+ assertArrayEquals(CANONICAL_MATCH_KEY, fodId.getMatchKey());
assertArrayEquals(payload, fodId.getPayload());
assertTrue(fodId.verify(factory.publicPem));
}
@@ -281,7 +293,7 @@ public void base64Roundtrip_PreservesAllFields() throws Exception {
assertEquals(fodId1.getFlags(), fodId2.getFlags());
assertEquals(fodId1.getLicenseId(), fodId2.getLicenseId());
- assertArrayEquals(fodId1.getHash(), fodId2.getHash());
+ assertArrayEquals(fodId1.getMatchKey(), fodId2.getMatchKey());
assertEquals(fodId1.getDomain(), fodId2.getDomain());
}
@@ -311,12 +323,12 @@ public void constructor_RandomPayload21Bytes_Parses() throws Exception {
FodId fodId = FodId.fromBase64(factory.signedOwidBase64(canonicalRandomPayload()));
assertEquals(CANONICAL_LICENSE_ID, fodId.getLicenseId());
- assertEquals(FodId.GUID_LENGTH, fodId.getHash().length);
+ assertEquals(FodId.GUID_LENGTH, fodId.getMatchKey().length);
byte[] expected = new byte[FodId.GUID_LENGTH];
for (int i = 0; i < expected.length; i++) {
expected[i] = (byte) (0x40 + i);
}
- assertArrayEquals(expected, fodId.getHash());
+ assertArrayEquals(expected, fodId.getMatchKey());
}
@Test
@@ -328,7 +340,7 @@ public void constructor_RandomPayloadOneByteShort_Throws() throws Exception {
}
@Test
- public void constructor_RandomPayloadLargerThanSpec_UsesFirst16ValueBytes()
+ public void constructor_RandomPayloadLargerThanSpec_UsesFirst16MatchKeyBytes()
throws Exception {
byte[] payload = new byte[FodId.PAYLOAD_LENGTH];
System.arraycopy(
@@ -340,7 +352,7 @@ public void constructor_RandomPayloadLargerThanSpec_UsesFirst16ValueBytes()
FodId fodId = FodId.fromBase64(factory.signedOwidBase64(payload));
assertEquals(IdType.RANDOM, fodId.getType());
- assertEquals(FodId.GUID_LENGTH, fodId.getHash().length);
+ assertEquals(FodId.GUID_LENGTH, fodId.getMatchKey().length);
}
@Test
@@ -360,13 +372,13 @@ public void constructor_ReservedHeaderOnly_Parses() throws Exception {
FodId fodId = FodId.fromBase64(factory.signedOwidBase64(payload));
assertEquals(IdType.RESERVED, fodId.getType());
- assertEquals(0, fodId.getHash().length);
+ assertEquals(0, fodId.getMatchKey().length);
}
// ----- Gap tests (runbook section 6b) -----
@Test
- public void compareTwo51Dids_SamePayload_SameValueDifferentEnvelopes()
+ public void compareTwo51Dids_SamePayload_SameMatchKeyDifferentEnvelopes()
throws Exception {
byte[] payload = canonicalPayload();
// The creator stamps "now" to the minute, so two reissues at
@@ -379,8 +391,8 @@ public void compareTwo51Dids_SamePayload_SameValueDifferentEnvelopes()
FodId fodA = FodId.fromBase64(a.asBase64());
FodId fodB = FodId.fromBase64(b.asBase64());
- // The value is stable across reissues...
- assertArrayEquals(fodA.getHash(), fodB.getHash());
+ // The match key is stable across reissues...
+ assertArrayEquals(fodA.getMatchKey(), fodB.getMatchKey());
// ...while the envelope differs.
assertNotEquals(fodA.getDate(), fodB.getDate());
assertFalse(Arrays.equals(fodA.getSignature(), fodB.getSignature()));
@@ -402,7 +414,7 @@ public void construction_DoesNotVerify() throws Exception {
assertEquals(CANONICAL_FLAGS, fodId.getFlags());
assertEquals(CANONICAL_LICENSE_ID, fodId.getLicenseId());
- assertArrayEquals(CANONICAL_HASH, fodId.getHash());
+ assertArrayEquals(CANONICAL_MATCH_KEY, fodId.getMatchKey());
}
@Test
@@ -413,7 +425,7 @@ public void fromOwid_HoldsTheEnvelopeItWasGiven() throws Exception {
FodId fodId = FodId.fromOwid(owid);
assertEquals(CANONICAL_FLAGS, fodId.getFlags());
- assertArrayEquals(CANONICAL_HASH, fodId.getHash());
+ assertArrayEquals(CANONICAL_MATCH_KEY, fodId.getMatchKey());
assertArrayEquals(owid.asByteArray(), fodId.asByteArray());
}
@@ -434,7 +446,7 @@ public void roundtrip_ThroughBytesConstructor_PreservesAllFields()
assertEquals(fodId1.getFlags(), fodId2.getFlags());
assertEquals(fodId1.getLicenseId(), fodId2.getLicenseId());
- assertArrayEquals(fodId1.getHash(), fodId2.getHash());
+ assertArrayEquals(fodId1.getMatchKey(), fodId2.getMatchKey());
assertEquals(fodId1.getDomain(), fodId2.getDomain());
}
@@ -456,7 +468,7 @@ public void fromBase64_AcceptsStandardUrlSafeAndUnpadded() throws Exception {
assertArrayEquals(fromStandard.asByteArray(), fromUrlSafe.asByteArray());
assertArrayEquals(fromStandard.asByteArray(), fromUnpadded.asByteArray());
- assertArrayEquals(CANONICAL_HASH, fromUnpadded.getHash());
+ assertArrayEquals(CANONICAL_MATCH_KEY, fromUnpadded.getMatchKey());
}
@Test
*
*