Skip to content

Commit

Permalink
Merge pull request #315 from Concordium/web3Id-proof
Browse files Browse the repository at this point in the history
Add function to create web3Id proof
  • Loading branch information
shjortConcordium authored Feb 19, 2024
2 parents 7120a3c + 3ae2453 commit ecde1ed
Show file tree
Hide file tree
Showing 24 changed files with 636 additions and 4 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## Unreleased changes
- Added `Web3IdProof` class with `getWeb3IdProof` method to create Presentations. (And supporting classes)

## 7.0.0
- Make the `energy` parameter for invoking an instance `Optional`.
- Parse the underlying reject reasons into `AccountTransactionDetails`.
Expand Down
2 changes: 1 addition & 1 deletion concordium-base
Submodule concordium-base updated 39 files
+1 −1 .github/workflows/build-test-sources.yaml
+12 −10 concordium-base.cabal
+6 −2 haskell-bins/generate-update-keys/Main.hs
+610 −0 haskell-src/Concordium/MerkleProofs.hs
+1 −1 haskell-src/Concordium/Types/Execution.hs
+12 −6 haskell-src/Concordium/Types/ProtocolVersion.hs
+2 −73 haskell-src/Concordium/Types/Transactions.hs
+0 −1 haskell-src/Concordium/Utils/Encryption.hs
+0 −1 haskell-src/Concordium/Utils/Serialization/Put.hs
+1 −0 haskell-tests/ConcordiumTests/Crypto/FFIVerify.hs
+141 −0 haskell-tests/ConcordiumTests/MerkleProofs.hs
+2 −0 haskell-tests/Spec.hs
+28 −155 identity-provider-service/Cargo.lock
+0 −1 identity-provider-service/Cargo.toml
+2 −2 idiss/Cargo.lock
+1 −1 idiss/Cargo.toml
+2 −2 mobile_wallet/Cargo.lock
+2 −2 mobile_wallet/Cargo.toml
+1 −1 package.yaml
+2 −2 rust-bins/Cargo.lock
+3 −2 rust-src/Cargo.lock
+2 −0 rust-src/concordium_base/CHANGELOG.md
+2 −2 rust-src/concordium_base/Cargo.toml
+8 −2 rust-src/wallet_library/CHANGELOG.md
+2 −1 rust-src/wallet_library/Cargo.toml
+1 −0 rust-src/wallet_library/resources/web3_id_request.json
+1 −0 rust-src/wallet_library/src/lib.rs
+62 −0 rust-src/wallet_library/src/proofs.rs
+8 −0 rust-src/wallet_library/src/test_helpers.rs
+2 −0 smart-contracts/contracts-common/concordium-contracts-common/CHANGELOG.md
+3 −3 smart-contracts/contracts-common/concordium-contracts-common/Cargo.toml
+2 −0 smart-contracts/contracts-common/concordium-contracts-common/src/schema.rs
+2 −0 smart-contracts/wasm-chain-integration/CHANGELOG.md
+3 −3 smart-contracts/wasm-chain-integration/Cargo.lock
+3 −3 smart-contracts/wasm-chain-integration/Cargo.toml
+2 −2 smart-contracts/wasm-test/Cargo.lock
+4 −0 smart-contracts/wasm-transform/CHANGELOG.md
+2 −2 smart-contracts/wasm-transform/Cargo.toml
+6 −1 stack.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -308,4 +308,12 @@ public static String getVerifiableCredentialBackupEncryptionKey(String seedAsHex
* If not successful, the 'err' field contains a {@link JNIError} detailing what went wrong.
*/
public static native String serializeCredentialDeploymentForSubmission(String input);

/**
* Creates a web3Id presentation for the given statement.
* @param input {@link Web3IdProofInput} serialized as JSON.
* @return JSON representing {@link StringResult}. If successful the field 'result' contains the
* {@link Web3IdProof} as JSON.
*/
public static native String createWeb3IdProof(String input);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.concordium.sdk.crypto.wallet.web3Id;

import java.util.Map;

import com.concordium.sdk.responses.accountinfo.credential.AttributeType;
import com.concordium.sdk.types.UInt32;
import com.fasterxml.jackson.annotation.JsonTypeName;

import lombok.Builder;
import lombok.Getter;
import lombok.extern.jackson.Jacksonized;

@Getter
@Builder
@Jacksonized
@JsonTypeName("account")
public class AccountCommitmentInput extends CommitmentInput {
private UInt32 issuer;
private Map<AttributeType,String> values;
private Map<AttributeType, String> randomness;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.concordium.sdk.crypto.wallet.web3Id;

import static com.fasterxml.jackson.annotation.JsonTypeInfo.As.PROPERTY;
import static com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME;

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;


@JsonTypeInfo(use = NAME, include = PROPERTY, property = "type")
@JsonSubTypes ({@Type (value = AccountCommitmentInput.class), @Type (value = Web3IssuerCommitmentInput.class)})
public abstract class CommitmentInput {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package com.concordium.sdk.crypto.wallet.web3Id;

import java.io.IOException;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import lombok.Builder;
import lombok.Getter;

@JsonSerialize(using = CredentialAttribute.CredentialAttributeTypeSerializer.class)
@JsonDeserialize(using = CredentialAttribute.CredentialAttributieTypeDeserializer.class)
@Builder
@Getter
public class CredentialAttribute {
enum CredentialAttributeType {
INT,
STRING,
TIMESTAMP;
}

private String value;
private CredentialAttributeType type;

static class CredentialAttributieTypeDeserializer extends JsonDeserializer<CredentialAttribute> {

@Override
public CredentialAttribute deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
JsonNode reference = p.getCodec().readTree(p);
if (reference.isNumber()) {
return new CredentialAttribute(reference.asText(), CredentialAttributeType.INT);
} else if (reference.isTextual()) {
return new CredentialAttribute(reference.asText(), CredentialAttributeType.STRING);
} else if (reference.has("type") && reference.get("type").asText().equals("date-time")
&& reference.has("timestamp")) {
return new CredentialAttribute(reference.get("timestamp").asText(), CredentialAttributeType.TIMESTAMP);
}
throw new JsonParseException(p, "Instantiation of Web3IdAtttribute failed due to invalid structure");
}
}

static class CredentialAttributeTypeSerializer extends JsonSerializer<CredentialAttribute> {
@Override
public void serialize(CredentialAttribute value, JsonGenerator gen, SerializerProvider serializers)
throws IOException {
switch (value.getType()) {
case INT:
gen.writeNumber(value.getValue());
break;
case STRING:
gen.writeString(value.getValue());
break;
case TIMESTAMP:
gen.writeStartObject();
gen.writeStringField("type", "date-time");
gen.writeStringField("timestamp", value.getValue());
gen.writeEndObject();
break;
default:
// The switch already covers every case of the given type, so this should never
// happen
throw new RuntimeException("Unreachable, invalid CredentialAttributeType: " + value.getType());
}
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.concordium.sdk.crypto.wallet.web3Id;

import java.util.List;

import com.concordium.sdk.crypto.wallet.web3Id.Statement.RequestStatement;

import lombok.Builder;
import lombok.Getter;
import lombok.extern.jackson.Jacksonized;

@Getter
@Builder
@Jacksonized
public class Request {
private final String challenge;
private final List<RequestStatement> credentialStatements;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.concordium.sdk.crypto.wallet.web3Id.Statement;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

import static com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME;

@JsonTypeInfo(use = NAME, include = As.PROPERTY, property = "type", visible = true)
@JsonSubTypes ({@Type (value = RevealStatement.class), @Type (value = RangeStatement.class), @Type (value = MembershipStatement.class), @Type (value = NonMembershipStatement.class)})
public abstract class AtomicStatement {
@JsonProperty("attributeTag")
public abstract String getAttributeTag();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.concordium.sdk.crypto.wallet.web3Id.Statement;

import java.util.List;

import com.concordium.sdk.crypto.wallet.web3Id.CredentialAttribute;
import com.fasterxml.jackson.annotation.JsonTypeName;

import lombok.Getter;

@Getter
@JsonTypeName("AttributeInSet")
public class MembershipStatement extends AtomicStatement {
private String attributeTag;
private List<CredentialAttribute> set;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.concordium.sdk.crypto.wallet.web3Id.Statement;

import java.util.List;

import com.concordium.sdk.crypto.wallet.web3Id.CredentialAttribute;
import com.fasterxml.jackson.annotation.JsonTypeName;

import lombok.Getter;

@Getter
@JsonTypeName("AttributeNotInSet")
public class NonMembershipStatement extends AtomicStatement {
private String attributeTag;
private List<CredentialAttribute> set;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.concordium.sdk.crypto.wallet.web3Id.Statement;

import com.concordium.sdk.crypto.wallet.web3Id.CredentialAttribute;
import com.concordium.sdk.responses.accountinfo.credential.AttributeType;
import com.fasterxml.jackson.annotation.JsonTypeName;

import lombok.Builder;
import lombok.Getter;
import lombok.extern.jackson.Jacksonized;

@JsonTypeName("AttributeInRange")
@Getter
@Builder
@Jacksonized
public class RangeStatement extends AtomicStatement {
private CredentialAttribute lower;
private CredentialAttribute upper;
private String attributeTag;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.concordium.sdk.crypto.wallet.web3Id.Statement;

import java.util.List;

import lombok.Builder;
import lombok.Getter;
import lombok.extern.jackson.Jacksonized;

@Getter
@Builder
@Jacksonized
public class RequestStatement {
private String id;
private List<String> type;
private List<AtomicStatement> statement;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.concordium.sdk.crypto.wallet.web3Id.Statement;

import com.fasterxml.jackson.annotation.JsonTypeName;

import lombok.Getter;

@Getter
@JsonTypeName("RevealAttribute")
public class RevealStatement extends AtomicStatement {
private String attributeTag;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.concordium.sdk.crypto.wallet.web3Id;

import com.concordium.sdk.crypto.CryptoJniNative;
import com.concordium.sdk.crypto.NativeResolver;
import com.concordium.sdk.crypto.wallet.StringResult;
import com.concordium.sdk.exceptions.CryptoJniException;
import com.concordium.sdk.serializing.JsonMapper;
import com.fasterxml.jackson.core.JsonProcessingException;

public class Web3IdProof {
// Static block to load native library.
static {
NativeResolver.loadLib();
}

/**
* Creates a Presentation of a web3IdProof.
* @param input the input required to generate the Presentiation
* @return a Presentation serialized as JSON
*/
public static String getWeb3IdProof(Web3IdProofInput input) {
StringResult result = null;
try {
String jsonStr = CryptoJniNative.createWeb3IdProof(JsonMapper.INSTANCE.writeValueAsString(input));
result = JsonMapper.INSTANCE.readValue(jsonStr, StringResult.class);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}

if (!result.isSuccess()) {
throw CryptoJniException.from(result.getErr());
}

return result.getResult();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.concordium.sdk.crypto.wallet.web3Id;

import java.util.List;

import com.concordium.sdk.responses.cryptographicparameters.CryptographicParameters;

import lombok.Builder;
import lombok.Getter;
import lombok.extern.jackson.Jacksonized;

/**
* The data needed to create a web3Id Presentation.
*/
@Getter
@Builder
@Jacksonized
public class Web3IdProofInput {
private final Request request;
private final List<CommitmentInput> commitmentInputs;
private final CryptographicParameters globalContext;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.concordium.sdk.crypto.wallet.web3Id;

import java.util.Map;

import com.fasterxml.jackson.annotation.JsonTypeName;

import lombok.Builder;
import lombok.Getter;
import lombok.extern.jackson.Jacksonized;

@Getter
@Builder
@Jacksonized
@JsonTypeName("web3Issuer")
public class Web3IssuerCommitmentInput extends CommitmentInput {
private String signature;
private String signer;
private Map<String, CredentialAttribute> values;
private Map<String, String> randomness;
}
Loading

0 comments on commit ecde1ed

Please sign in to comment.