Abstract
Taken from the Mentorship Description
Hyperledger AnonCreds includes specifications and implementations of AnonCreds (Anonymous Credentials) Zero-Knowledge Proof (ZKP)-based verifiable credentials. AnonCreds extends the capabilities of “typical” verifiable credentials by including important privacy-preserving features including selective disclosure, ZKP predicates (e.g., proving I’m older than 21 based on my date of birth without sharing my date of birth), and not revealing any correlatable identifiers in presenting credentials. The version 1.0 specification (based on CL-Signatures as initially implemented in Hyperledger Indy) is near completion, and work has begun on the version 2.0 specification that will retain and extend the privacy-preserving features of AnonCreds v1.0, while improving capabilities, performance, extensibility, and security. An implementation based on the Version 2.0 specification will occur in parallel with the development of the specification.
In this project, the mentee will participate directly in the specification development process.
- For the Version 1.0 specification, the primary task will be to extract the cryptographic primitives from identified sources, confirm alignment with the Rust implementation of AnonCreds, and include the cryptographic primitives in the specification. This is the last step of the specification to make it ready for submission to a standards development organization (SDO).
- The Version 2.0 specification, the task will be similar, but the work will extend the focus as appropriate to implementation of the cryptographic primitives.
Mentor and Mentee
Mentor:
Timezone:
Rocketchat (hyperledger):
Mentee:
Timezone:
Fork of official Stephen Curran, Mike Lodder
Time zones: Pacific Time, North America, Mountain Time, North America
Discord: swcurran, mikelodder
Mentee: Aritra Bhaduri
Time zone: India Time
Official repository for this project:
Deliverables
Milestones
Evaluation 1:
Evaluation 2:
Evaluation 3:
Evaluation 4:
Timeline
...
Week #
...
Week
...
Activity
...
Status
...
0
...
May 24 - May 30
...
First contact with mentor and discussion of solutions.
...
✅
...
1-2
...
May 31 - June 13
...
3-4
...
June 14 - June 27
...
5-6
...
June 28 - July 11
Evaluation 1
...
7-8
...
July 12 - July 25
...
9-10
...
July 26 - August 8
...
11-12
...
August 9 - August 22
Evaluation 2
...
13-14
...
August 23 - September 5
...
15-16
...
September 6 - September 19
...
17-18
...
September 20 - October 3
Evaluation 3
...
19-20
...
October 4 - October 17
...
21-22
...
October 18 - October 31
...
23-24
...
November 1 - November 14
Evaluation 4
...
Methodology
REPLACE: After I start coding each milestone, my mentor and I will have a planning session to define the best way to tackle the challenges. Then, I will execute the planning and schedule a review session with my mentor. If everything is working and we agree upon the implemented solution, I am going to write tests and update the Solang documentation website with the most recent features. In addition to those meetings, we are doing weekly calls to review the progress of the project.
Following this methodology, I intend to maintain the transparency of my work and keep the Solang users updated with the most recent features and documentation.
Documentation
REPLACE: Unused variable detection
A variable in solidity can have three scopes: a global scope, a contract scope (state variables) and a function scope. Global variables can only be constant variables. State variables reside inside a contract. After solang parses a solidity file and builds the AST (abstract syntax tree), all data is saved inside the struct Namespace, which contains a vector of contracts. Inside Contracts there is a vector of variables (struct Variable) that saves state variables. Global constant variables reside in a vector of constants inside Namespace and local variables are saved in a each function's symbol table.
We added a boolean variable read inside struct variable to signal that a variable has been used in the code. At first, used is initialized to false. Once we parse an expression that uses the variable, we set it to true. In addition, we included a boolean variable assigned to signal that a variable has been assigned. Once we parse an assignment expression, we set this variable to true. The aforementioned modification will allow us to emit warnings for unused variables and unassigned ones.
For example, in the following contract, we should expect three warnings. The variables a and b have been assigned, but never read and variable c has never been read nor assigned.
Code Block | ||||
---|---|---|---|---|
| ||||
contract Test {
function get() public pure {
uint32 a = 1;
uint32 b;
b = 1;
uint32 c;
uint32 d;
d = 1;
uint32 e;
e = d*5;
d = e/5;
}
} |
When running solidity, we got the following warnings as expected:
Code Block | ||
---|---|---|
| ||
test.sol:4:16-17: warning: local variable 'a' has been assigned, but never read
test.sol:5:16-17: warning: local variable 'b' has been assigned, but never read
test.sol:7:16-17: warning: local variable 'c' has never been read nor assigned |
Likewise, in the next contract, we expect to see warnings because local variable b32 has never been assigned a values, but has been read and storage variable byteArr has been assigned, but never read.
Code Block | ||||
---|---|---|---|---|
| ||||
contract Test {
bytes byteArr;
bytes32 baRR;
function get() public {
string memory s = "Test";
byteArr = bytes(s);
uint16 a = 1;
uint8 b;
b = uint8(a);
uint256 c;
c = b;
bytes32 b32;
bytes memory char = bytes(bytes32(uint(a) * 2 ** (8 * b)));
baRR = bytes32(c);
bytes32 cdr = bytes32(char);
assert(b32 == baRR);
if(b32 != cdr) {
}
}
} |
After running solidity, we got the following warnings:
Code Block | ||
---|---|---|
| ||
test.sol:15:17-20: warning: local variable 'b32' has never been assigned a value, but has been read
test.sol:3:5-18: warning: storage variable 'byteArr' has been assigned, but never read |
Unused variable elimination
Before creating the Control Flow Graph (CFG), Solang generates a variable table from the AST. During that phase, we can raise a warning when we see an unused variable and leave it out of the CFG. Using the id variable inside the Variable struct, we can backtrack the position where the variable appeared in the file and print a meaningful warning, containing the file name and line position. If the variable has only been assigned within a function, but has never been read, in addition to eliminating the variable declaration, we remove all the assignments from the intermediate representation.
Warning for undefined variables
During the codegen phase, we use the reaching definitions implementation to check if an undefined definition reaches the variable we are parsing. If so, we will raise an error. Using the id variable inside the Variable struct, we backtrack the variable’s location in the source file and emit a complete warning. All warnings will be saved into the diagnostic vector, which is a vector of struct Diagnostics, containing the error type, error message and error position.
Common subexpression elimination
We perform common subexpression elimination using two passes over the Control Flow Graph (CFG). During the first on, we build a graph to track existing expressions and detect repeated ones. During the second pass, we replace the repeated expressions by a temporary variable, which assumes the value of the expression. The example below contains multiple repeated expressions:
Code Block | ||
---|---|---|
| ||
contract {
function csePass(int a, int b) {
int x = a*b-5;
if (x > 0) {
x = a*b-19;
} else {
x = a*b*a;
}
return x+a*b;
}
} |
The expression `a*b` is repeated throughout the code and will be saved to a temporary variable, which will be placed wherever there is a `a*b` expression
- Specification: https://github.com/hyperledger/anoncreds-spec
- Implementation: https://github.com/hyperledger/anoncreds-rs
- Published Specification: https://hyperledger.github.io/anoncreds-spec
Deliverables
The primary deliverable is the population of the AnonCreds specification with the cryptographic algorithms used in the four AnonCreds operations (setup, issuance, presentation, and verification), including the impact of revocation on those operations. Based on the time available after that work we may look to have the project also include the AnonCreds V2.0 cryptographic primitives. The Milestones are each of the operations, plus revocation. The approach is defined in the methodology section.
The cryptography primitives should be put inline into the specification. The BBS+ Signatures IETF Specification uses an approach that should be followed, albeit with Latex where it is helpful.
Milestones
Setup:
- As is done in the BBS+ Signatures IETF Specification, add a "Notations" section to the specification, and populate it as appropriate based on the cryptographic algorithms in the specification.
- Credential Definition generation process (noting the public and private portions) – no revocation.
Issuance:
NOTE: In this section there is a lot of back and forth of data elements (e.g. two nonces, three correctness proofs). As the details are added, feel free to adjust the text to make it as easy as possible for the reader to understand the process.
- Terminology:
- Blinding Factor
- Signature Correctness Proof, Blinded Secret Correctness Proof
- Credential Offer:
- Verify the specification of the Credential Offer key correctness proof and verification of the key correctness proof.
- Credential Request:
- Description of the nonce in the credential request data model.
- Document how the nonce from the Credential Offer is used.
- Verify how the blinding link secret is generated.
- Document the items in the blinded link secret data model and how they are generated.
- Document the items in the blinded link secret correctness proof data model and how they are generated.
- Issue Credential:
- Document how the nonce from the credential offer is verified in the credential generation.
- Document how the blinded kink secret correctness proof is verified.
- Document how the nonce from the credential request is used.
- Document how the Credential Signature is generated.
- Document how the Credential Signature Correctness Proof is generated.
- Receiving a Credential
- Document how the nonce from the Credential Request is verified.
- Document how the Credential Signature Correctness Proof is verified.
Presentation:
NOTE: This section needs to be reworked to be more in the style of the rest of the specification, with a description of the process, cryptographic processes invoked, and the data models that result are described. Stephen Curran to do that step.
NOTE: AFAIK, the AnonCreds library does not include the credential searching, nor does it deal with the wallet, and as part of the rewrite, those items will be removed. The current "Step 5" will update to cover the data passed in to the presentation generation process, how the proofs from a source credential is produced (credential and predicate), how the aggregate proof is generated, and how the data is mapped back into the response to the proof request (e.g. requested_attr groups, unrevealed_attrs, self_attested_attrs and predicates).
- Document the items in the and generation process for a credential proof.
- Document the items and generation process for a predicate proof.
- Document the Aggregate proof
- Document how the full presentation data model is populated.
Verification:
NOTE: This section needs to be reworked to be more in the style of the rest of the specification, with a description of the process, cryptographic processes invoked, and the data models that result are described. Stephen Curran to do that step.
- Document how a credential proof is verified.
- Document how a predicate proof is verified
- Document how the aggregate proof is verified.
Revocation:
NOTE: Section 10.3 will be re-written to be less opinionated on the format of the RevRegEntry, allowing it to be either a list of deltas or the full state of the RevReg, e.g. a True/False bit for each credential in the registry.
- Setup:
- Document the additional data in the credential definition data models (public and private) with revocation support, including where needed how the data is generated (Section 7.2.3).
- Document the data in the Revocation Registry Definition data models (public and private) and how it is generated.
- Document the Tails File generation process and file format. DONE!
- Document the data in a Revocation Registry Entry data model, and the generation process of those elements.
- Issuance:
- Describe the revocation part of the Credential data model and how the elements are generated.
- Presentation:
- Describe how the witness is created for the non-revocation proof, given the tails file, accumulator (if needed), and a revocation registry state object.
- Document the values in the non-revocation proof data model for a source credential and how the values are generated.
- Verification:
- Document how the non-revocation proof is verified.
Timeline
It is extremely difficult to define a timeline for the work to be done on this project, as it will depend on far too many factors that we don't know right now. Instead, we will begin with the assumption that the work will be done in sequence as listed in the Milestones section. We will communicate continuously on Discord and meet every 2nd week to discuss progress and adjust the Milestones. For example, we might change the ordering of the work, add new milestones (such as adding work on AnonCreds v2.0), or drop milestones.
Every second of those meetings will include an "evaluation" of the work completed that is sufficient to meet the needs of the Hyperledger Mentorship Program (to be determined).
Methodology
For each item to be documented, the following approach is suggested.
- Review the source documents and AnonCreds implementation.
- Document a minimum draft of the process as the basis for questions about the process.
- Ask questions about the process in Discord.
- If ever the online back and forth is ineffective, call a meeting. No need to spend time writing back and forth messages about an issue that needs a face-to-face discussion.
- Refine the document and confirm the implementation.
- Identify any information that should be updated in the Terminology and Notations section of the document from the newly documented item.
- Submit a PR to the specification for review.
As we gain experience, feel free to adjust this approach to what works best/most efficient.