Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add function to create web3Id proof #315

Merged
merged 5 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 {
orhoj marked this conversation as resolved.
Show resolved Hide resolved
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
Loading