--- /dev/null
+package org.asamk.signal.manager.groups;
+
+import org.asamk.signal.manager.storage.groups.GroupInfo;
+import org.asamk.signal.manager.storage.groups.GroupInfoV1;
+import org.asamk.signal.manager.storage.groups.GroupInfoV2;
+import org.signal.zkgroup.InvalidInputException;
+import org.signal.zkgroup.groups.GroupMasterKey;
+import org.signal.zkgroup.groups.GroupSecretParams;
+import org.whispersystems.libsignal.kdf.HKDFv3;
+import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
+import org.whispersystems.signalservice.api.messages.SignalServiceGroup;
+import org.whispersystems.signalservice.api.messages.SignalServiceGroupContext;
+import org.whispersystems.signalservice.api.messages.SignalServiceGroupV2;
+
+public class GroupUtils {
+
+ public static void setGroupContext(
+ final SignalServiceDataMessage.Builder messageBuilder, final GroupInfo groupInfo
+ ) {
+ if (groupInfo instanceof GroupInfoV1) {
+ SignalServiceGroup group = SignalServiceGroup.newBuilder(SignalServiceGroup.Type.DELIVER)
+ .withId(groupInfo.getGroupId().serialize())
+ .build();
+ messageBuilder.asGroupMessage(group);
+ } else {
+ final GroupInfoV2 groupInfoV2 = (GroupInfoV2) groupInfo;
+ SignalServiceGroupV2 group = SignalServiceGroupV2.newBuilder(groupInfoV2.getMasterKey())
+ .withRevision(groupInfoV2.getGroup() == null ? 0 : groupInfoV2.getGroup().getRevision())
+ .build();
+ messageBuilder.asGroupMessage(group);
+ }
+ }
+
+ public static GroupId getGroupId(SignalServiceGroupContext context) {
+ if (context.getGroupV1().isPresent()) {
+ return GroupId.v1(context.getGroupV1().get().getGroupId());
+ } else if (context.getGroupV2().isPresent()) {
+ return getGroupIdV2(context.getGroupV2().get().getMasterKey());
+ } else {
+ return null;
+ }
+ }
+
+ public static GroupIdV2 getGroupIdV2(GroupSecretParams groupSecretParams) {
+ return GroupId.v2(groupSecretParams.getPublicParams().getGroupIdentifier().serialize());
+ }
+
+ public static GroupIdV2 getGroupIdV2(GroupMasterKey groupMasterKey) {
+ final GroupSecretParams groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupMasterKey);
+ return getGroupIdV2(groupSecretParams);
+ }
+
+ public static GroupIdV2 getGroupIdV2(GroupIdV1 groupIdV1) {
+ final GroupSecretParams groupSecretParams = GroupSecretParams.deriveFromMasterKey(deriveV2MigrationMasterKey(
+ groupIdV1));
+ return getGroupIdV2(groupSecretParams);
+ }
+
+ private static GroupMasterKey deriveV2MigrationMasterKey(GroupIdV1 groupIdV1) {
+ try {
+ return new GroupMasterKey(new HKDFv3().deriveSecrets(groupIdV1.serialize(),
+ "GV2 Migration".getBytes(),
+ GroupMasterKey.SIZE));
+ } catch (InvalidInputException e) {
+ throw new AssertionError(e);
+ }
+ }
+}