reputrans 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +114 -0
- package/circuits/composite/target/composite.json +1 -0
- package/circuits/field_disclosure/target/field_disclosure.json +1 -0
- package/circuits/map_to_curve/target/map_to_curve.json +1 -0
- package/circuits/poseidon_compat/target/poseidon_compat.json +1 -0
- package/circuits/range_proof/target/range_proof.json +1 -0
- package/circuits/set_membership/target/set_membership.json +1 -0
- package/circuits/signature_verify/target/signature_verify.json +1 -0
- package/dist/cli/src/auto-detect.d.ts +9 -0
- package/dist/cli/src/auto-detect.d.ts.map +1 -0
- package/dist/cli/src/auto-detect.js +21 -0
- package/dist/cli/src/auto-detect.js.map +1 -0
- package/dist/cli/src/commands/inspect.d.ts +6 -0
- package/dist/cli/src/commands/inspect.d.ts.map +1 -0
- package/dist/cli/src/commands/inspect.js +43 -0
- package/dist/cli/src/commands/inspect.js.map +1 -0
- package/dist/cli/src/commands/issue.d.ts +8 -0
- package/dist/cli/src/commands/issue.d.ts.map +1 -0
- package/dist/cli/src/commands/issue.js +107 -0
- package/dist/cli/src/commands/issue.js.map +1 -0
- package/dist/cli/src/commands/keygen.d.ts +7 -0
- package/dist/cli/src/commands/keygen.d.ts.map +1 -0
- package/dist/cli/src/commands/keygen.js +39 -0
- package/dist/cli/src/commands/keygen.js.map +1 -0
- package/dist/cli/src/commands/prove.d.ts +9 -0
- package/dist/cli/src/commands/prove.d.ts.map +1 -0
- package/dist/cli/src/commands/prove.js +139 -0
- package/dist/cli/src/commands/prove.js.map +1 -0
- package/dist/cli/src/commands/verify.d.ts +6 -0
- package/dist/cli/src/commands/verify.d.ts.map +1 -0
- package/dist/cli/src/commands/verify.js +63 -0
- package/dist/cli/src/commands/verify.js.map +1 -0
- package/dist/cli/src/index.d.ts +3 -0
- package/dist/cli/src/index.d.ts.map +1 -0
- package/dist/cli/src/index.js +45 -0
- package/dist/cli/src/index.js.map +1 -0
- package/dist/sdk/src/circuit-loader.d.ts +19 -0
- package/dist/sdk/src/circuit-loader.d.ts.map +1 -0
- package/dist/sdk/src/circuit-loader.js +65 -0
- package/dist/sdk/src/circuit-loader.js.map +1 -0
- package/dist/sdk/src/eddsa.d.ts +63 -0
- package/dist/sdk/src/eddsa.d.ts.map +1 -0
- package/dist/sdk/src/eddsa.js +177 -0
- package/dist/sdk/src/eddsa.js.map +1 -0
- package/dist/sdk/src/encoder.d.ts +49 -0
- package/dist/sdk/src/encoder.d.ts.map +1 -0
- package/dist/sdk/src/encoder.js +117 -0
- package/dist/sdk/src/encoder.js.map +1 -0
- package/dist/sdk/src/identity.d.ts +69 -0
- package/dist/sdk/src/identity.d.ts.map +1 -0
- package/dist/sdk/src/identity.js +110 -0
- package/dist/sdk/src/identity.js.map +1 -0
- package/dist/sdk/src/index.d.ts +18 -0
- package/dist/sdk/src/index.d.ts.map +1 -0
- package/dist/sdk/src/index.js +18 -0
- package/dist/sdk/src/index.js.map +1 -0
- package/dist/sdk/src/poseidon.d.ts +33 -0
- package/dist/sdk/src/poseidon.d.ts.map +1 -0
- package/dist/sdk/src/poseidon.js +59 -0
- package/dist/sdk/src/poseidon.js.map +1 -0
- package/dist/sdk/src/proof-request.d.ts +58 -0
- package/dist/sdk/src/proof-request.d.ts.map +1 -0
- package/dist/sdk/src/proof-request.js +68 -0
- package/dist/sdk/src/proof-request.js.map +1 -0
- package/dist/sdk/src/prover.d.ts +38 -0
- package/dist/sdk/src/prover.d.ts.map +1 -0
- package/dist/sdk/src/prover.js +108 -0
- package/dist/sdk/src/prover.js.map +1 -0
- package/dist/sdk/src/vc-parser.d.ts +50 -0
- package/dist/sdk/src/vc-parser.d.ts.map +1 -0
- package/dist/sdk/src/vc-parser.js +96 -0
- package/dist/sdk/src/vc-parser.js.map +1 -0
- package/dist/sdk/src/verifier.d.ts +19 -0
- package/dist/sdk/src/verifier.d.ts.map +1 -0
- package/dist/sdk/src/verifier.js +31 -0
- package/dist/sdk/src/verifier.js.map +1 -0
- package/dist/verifier/src/did-resolver.d.ts +36 -0
- package/dist/verifier/src/did-resolver.d.ts.map +1 -0
- package/dist/verifier/src/did-resolver.js +179 -0
- package/dist/verifier/src/did-resolver.js.map +1 -0
- package/dist/verifier/src/index.d.ts +2 -0
- package/dist/verifier/src/index.d.ts.map +1 -0
- package/dist/verifier/src/index.js +9 -0
- package/dist/verifier/src/index.js.map +1 -0
- package/dist/verifier/src/server.d.ts +6 -0
- package/dist/verifier/src/server.d.ts.map +1 -0
- package/dist/verifier/src/server.js +75 -0
- package/dist/verifier/src/server.js.map +1 -0
- package/dist/verifier/src/verify.d.ts +20 -0
- package/dist/verifier/src/verify.d.ts.map +1 -0
- package/dist/verifier/src/verify.js +97 -0
- package/dist/verifier/src/verify.js.map +1 -0
- package/package.json +41 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity management for REPUTRANS Provars.
|
|
3
|
+
*
|
|
4
|
+
* All operations use Poseidon hash (NOT Pedersen) for consistency
|
|
5
|
+
* with the circuit layer. Generates master identities, derives
|
|
6
|
+
* platform-specific keys, and computes nullifiers.
|
|
7
|
+
*
|
|
8
|
+
* Naming: Provar = credential holder, Arbiter = verifier.
|
|
9
|
+
*/
|
|
10
|
+
import { poseidonHash, BN254_FIELD_ORDER } from './poseidon.js';
|
|
11
|
+
/**
|
|
12
|
+
* Generate a cryptographically random BN254 field element.
|
|
13
|
+
*/
|
|
14
|
+
function randomFieldElement() {
|
|
15
|
+
const bytes = new Uint8Array(32);
|
|
16
|
+
crypto.getRandomValues(bytes);
|
|
17
|
+
let val = 0n;
|
|
18
|
+
for (const b of bytes)
|
|
19
|
+
val = (val << 8n) | BigInt(b);
|
|
20
|
+
// Reduce mod field order to get a valid 254-bit element
|
|
21
|
+
return val % BN254_FIELD_ORDER;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Generate a new Provar master identity.
|
|
25
|
+
*
|
|
26
|
+
* The master secret is a random BN254 field element.
|
|
27
|
+
* The commitment is poseidon(masterSecret, 0) - a binding commitment
|
|
28
|
+
* that can be registered in an anonymity set without revealing the secret.
|
|
29
|
+
*/
|
|
30
|
+
export function generateIdentity() {
|
|
31
|
+
const masterSecret = randomFieldElement();
|
|
32
|
+
const commitment = poseidonHash(masterSecret, 0n);
|
|
33
|
+
return { masterSecret, commitment };
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Reconstruct identity from an existing master secret.
|
|
37
|
+
*/
|
|
38
|
+
export function identityFromSecret(masterSecret) {
|
|
39
|
+
if (masterSecret < 0n || masterSecret >= BN254_FIELD_ORDER) {
|
|
40
|
+
throw new Error('Master secret must be a valid BN254 field element');
|
|
41
|
+
}
|
|
42
|
+
const commitment = poseidonHash(masterSecret, 0n);
|
|
43
|
+
return { masterSecret, commitment };
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Derive a platform-specific key from the master secret.
|
|
47
|
+
*
|
|
48
|
+
* key = poseidon(masterSecret, platformId)
|
|
49
|
+
*
|
|
50
|
+
* This allows different keys per platform while maintaining
|
|
51
|
+
* a single master identity. The platform cannot link back to
|
|
52
|
+
* the master secret or to keys on other platforms.
|
|
53
|
+
*/
|
|
54
|
+
export function derivePlatformKey(masterSecret, platformId) {
|
|
55
|
+
const key = poseidonHash(masterSecret, platformId);
|
|
56
|
+
return { platformId, key };
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Compute a nullifier for replay prevention.
|
|
60
|
+
*
|
|
61
|
+
* nullifier = poseidon(masterSecret, contextId)
|
|
62
|
+
*
|
|
63
|
+
* The context is typically a domain separator (e.g. hash of the
|
|
64
|
+
* Arbiter's address + session nonce). Same master secret + same context
|
|
65
|
+
* always produces the same nullifier, preventing double-spending
|
|
66
|
+
* without revealing the identity.
|
|
67
|
+
*/
|
|
68
|
+
export function computeNullifier(masterSecret, contextId) {
|
|
69
|
+
return poseidonHash(masterSecret, contextId);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Convert a string context (e.g. "arbiter:0x1234:session:5") into a
|
|
73
|
+
* field element suitable for nullifier computation.
|
|
74
|
+
*
|
|
75
|
+
* Uses Poseidon hash of packed chunks for collision resistance,
|
|
76
|
+
* rather than raw byte packing which is vulnerable to collisions
|
|
77
|
+
* on inputs longer than 31 bytes.
|
|
78
|
+
*/
|
|
79
|
+
export function contextToField(context) {
|
|
80
|
+
const encoder = new TextEncoder();
|
|
81
|
+
const bytes = encoder.encode(context);
|
|
82
|
+
// Pack bytes into 31-byte field elements (BN254 safe)
|
|
83
|
+
const chunks = [];
|
|
84
|
+
for (let i = 0; i < bytes.length; i += 31) {
|
|
85
|
+
let val = 0n;
|
|
86
|
+
const end = Math.min(i + 31, bytes.length);
|
|
87
|
+
for (let j = i; j < end; j++) {
|
|
88
|
+
val = (val << 8n) | BigInt(bytes[j]);
|
|
89
|
+
}
|
|
90
|
+
chunks.push(val);
|
|
91
|
+
}
|
|
92
|
+
// Hash chunks pairwise with Poseidon for collision resistance
|
|
93
|
+
if (chunks.length === 0)
|
|
94
|
+
return poseidonHash(0n, 0n);
|
|
95
|
+
if (chunks.length === 1)
|
|
96
|
+
return poseidonHash(chunks[0], 0n);
|
|
97
|
+
let result = poseidonHash(chunks[0], chunks[1]);
|
|
98
|
+
for (let i = 2; i < chunks.length; i++) {
|
|
99
|
+
result = poseidonHash(result, chunks[i]);
|
|
100
|
+
}
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Compute a Poseidon commitment of the master secret.
|
|
105
|
+
* This is the value registered in the anonymity set.
|
|
106
|
+
*/
|
|
107
|
+
export function computeCommitment(masterSecret) {
|
|
108
|
+
return poseidonHash(masterSecret, 0n);
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../../sdk/src/identity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export { poseidonHash, poseidonHashEdDSA, BN254_FIELD_ORDER } from './poseidon.js';
|
|
2
|
+
export { sign, verify, getPublicKey, BJJ, G, IDENTITY } from './eddsa.js';
|
|
3
|
+
export type { Point, EdDSASignature } from './eddsa.js';
|
|
4
|
+
export { parseVC, extractSubjectFields, getIssuerId, VCParseError } from './vc-parser.js';
|
|
5
|
+
export type { VerifiableCredential, CredentialSubject, CredentialProof } from './vc-parser.js';
|
|
6
|
+
export { encodeCredential, buildMerkleTree, getMerklePath, stringToField, FIELD_TREE_DEPTH, MAX_LEAVES, } from './encoder.js';
|
|
7
|
+
export type { EncodedCredential, MerklePath } from './encoder.js';
|
|
8
|
+
export { validateProofRequest, createDisclosureRequest, createRangeRequest, ProofRequestError, } from './proof-request.js';
|
|
9
|
+
export type { ProofRequest, ProofResponse, Predicate, PredicateOperator, } from './proof-request.js';
|
|
10
|
+
export { generateIdentity, identityFromSecret, derivePlatformKey, computeNullifier, computeCommitment, contextToField, } from './identity.js';
|
|
11
|
+
export type { ProvarIdentity, DerivedKey } from './identity.js';
|
|
12
|
+
export { loadCircuit } from './circuit-loader.js';
|
|
13
|
+
export type { CircuitName } from './circuit-loader.js';
|
|
14
|
+
export { createProver } from './prover.js';
|
|
15
|
+
export type { Prover, CompiledCircuit } from './prover.js';
|
|
16
|
+
export { createVerifier } from './verifier.js';
|
|
17
|
+
export type { Verifier } from './verifier.js';
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../sdk/src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACnF,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC1E,YAAY,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGxD,OAAO,EAAE,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC1F,YAAY,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAG/F,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,UAAU,GACX,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAGlE,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,YAAY,EACZ,aAAa,EACb,SAAS,EACT,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhE,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG3D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// -- Cryptographic primitives --
|
|
2
|
+
export { poseidonHash, poseidonHashEdDSA, BN254_FIELD_ORDER } from './poseidon.js';
|
|
3
|
+
export { sign, verify, getPublicKey, BJJ, G, IDENTITY } from './eddsa.js';
|
|
4
|
+
// -- VC parsing --
|
|
5
|
+
export { parseVC, extractSubjectFields, getIssuerId, VCParseError } from './vc-parser.js';
|
|
6
|
+
// -- Encoding --
|
|
7
|
+
export { encodeCredential, buildMerkleTree, getMerklePath, stringToField, FIELD_TREE_DEPTH, MAX_LEAVES, } from './encoder.js';
|
|
8
|
+
// -- Proof request/response protocol --
|
|
9
|
+
export { validateProofRequest, createDisclosureRequest, createRangeRequest, ProofRequestError, } from './proof-request.js';
|
|
10
|
+
// -- Identity --
|
|
11
|
+
export { generateIdentity, identityFromSecret, derivePlatformKey, computeNullifier, computeCommitment, contextToField, } from './identity.js';
|
|
12
|
+
// -- Circuit loader --
|
|
13
|
+
export { loadCircuit } from './circuit-loader.js';
|
|
14
|
+
// -- Prover --
|
|
15
|
+
export { createProver } from './prover.js';
|
|
16
|
+
// -- Verifier --
|
|
17
|
+
export { createVerifier } from './verifier.js';
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../sdk/src/index.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACnF,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG1E,mBAAmB;AACnB,OAAO,EAAE,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG1F,iBAAiB;AACjB,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,UAAU,GACX,MAAM,cAAc,CAAC;AAGtB,wCAAwC;AACxC,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAQ5B,iBAAiB;AACjB,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,GACf,MAAM,eAAe,CAAC;AAGvB,uBAAuB;AACvB,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGlD,eAAe;AACf,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,iBAAiB;AACjB,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Poseidon hash wrapper - uses poseidon-lite which implements the original
|
|
3
|
+
* Poseidon hash (circomlib/IAIK BN254 constants).
|
|
4
|
+
*
|
|
5
|
+
* This matches Noir's std::hash::poseidon::bn254 exactly because both use
|
|
6
|
+
* the same parameter set:
|
|
7
|
+
* - Field: BN254 scalar field (21888242871839275222246405745257275088548364400416034343698204186575808495617)
|
|
8
|
+
* - S-box: x^5 (alpha = 5)
|
|
9
|
+
* - Full rounds (RF): 8
|
|
10
|
+
* - Partial rounds (RP): varies by width (56 for t=3, 57 for t=4-7)
|
|
11
|
+
* - Round constants: IAIK/circomlib BN254 Poseidon constants
|
|
12
|
+
* - MDS matrix: Cauchy construction from the Poseidon paper
|
|
13
|
+
*
|
|
14
|
+
* WARNING: Do NOT use bb.poseidon2Hash() - that is Poseidon2 (Aztec variant)
|
|
15
|
+
* which uses different round constants, a different partial round structure,
|
|
16
|
+
* and produces different outputs. Noir's eddsa_poseidon_verify uses original Poseidon.
|
|
17
|
+
*/
|
|
18
|
+
/** BN254 scalar field modulus */
|
|
19
|
+
export declare const BN254_FIELD_ORDER = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
|
|
20
|
+
/**
|
|
21
|
+
* Compute Poseidon hash matching Noir's std::hash::poseidon::bn254.
|
|
22
|
+
*
|
|
23
|
+
* @param inputs - 2 to 6 field elements (bigints < BN254_FIELD_ORDER)
|
|
24
|
+
* @returns The Poseidon hash as a bigint
|
|
25
|
+
* @throws If arity is not 2-6 or inputs are out of range
|
|
26
|
+
*/
|
|
27
|
+
export declare function poseidonHash(...inputs: bigint[]): bigint;
|
|
28
|
+
/**
|
|
29
|
+
* Poseidon hash for EdDSA verification: H(R8.x, R8.y, A.x, A.y, msg)
|
|
30
|
+
* This is the exact hash used inside Noir's eddsa_poseidon_verify.
|
|
31
|
+
*/
|
|
32
|
+
export declare function poseidonHashEdDSA(r8x: bigint, r8y: bigint, ax: bigint, ay: bigint, msg: bigint): bigint;
|
|
33
|
+
//# sourceMappingURL=poseidon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"poseidon.d.ts","sourceRoot":"","sources":["../../../sdk/src/poseidon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAQH,iCAAiC;AACjC,eAAO,MAAM,iBAAiB,iFAAiF,CAAC;AAUhH;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAcxD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,MAAM,GACV,MAAM,CAER"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Poseidon hash wrapper - uses poseidon-lite which implements the original
|
|
3
|
+
* Poseidon hash (circomlib/IAIK BN254 constants).
|
|
4
|
+
*
|
|
5
|
+
* This matches Noir's std::hash::poseidon::bn254 exactly because both use
|
|
6
|
+
* the same parameter set:
|
|
7
|
+
* - Field: BN254 scalar field (21888242871839275222246405745257275088548364400416034343698204186575808495617)
|
|
8
|
+
* - S-box: x^5 (alpha = 5)
|
|
9
|
+
* - Full rounds (RF): 8
|
|
10
|
+
* - Partial rounds (RP): varies by width (56 for t=3, 57 for t=4-7)
|
|
11
|
+
* - Round constants: IAIK/circomlib BN254 Poseidon constants
|
|
12
|
+
* - MDS matrix: Cauchy construction from the Poseidon paper
|
|
13
|
+
*
|
|
14
|
+
* WARNING: Do NOT use bb.poseidon2Hash() - that is Poseidon2 (Aztec variant)
|
|
15
|
+
* which uses different round constants, a different partial round structure,
|
|
16
|
+
* and produces different outputs. Noir's eddsa_poseidon_verify uses original Poseidon.
|
|
17
|
+
*/
|
|
18
|
+
import { poseidon2 } from 'poseidon-lite/poseidon2';
|
|
19
|
+
import { poseidon3 } from 'poseidon-lite/poseidon3';
|
|
20
|
+
import { poseidon4 } from 'poseidon-lite/poseidon4';
|
|
21
|
+
import { poseidon5 } from 'poseidon-lite/poseidon5';
|
|
22
|
+
import { poseidon6 } from 'poseidon-lite/poseidon6';
|
|
23
|
+
/** BN254 scalar field modulus */
|
|
24
|
+
export const BN254_FIELD_ORDER = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
|
|
25
|
+
const hashFns = {
|
|
26
|
+
2: (inputs) => poseidon2(inputs),
|
|
27
|
+
3: (inputs) => poseidon3(inputs),
|
|
28
|
+
4: (inputs) => poseidon4(inputs),
|
|
29
|
+
5: (inputs) => poseidon5(inputs),
|
|
30
|
+
6: (inputs) => poseidon6(inputs),
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Compute Poseidon hash matching Noir's std::hash::poseidon::bn254.
|
|
34
|
+
*
|
|
35
|
+
* @param inputs - 2 to 6 field elements (bigints < BN254_FIELD_ORDER)
|
|
36
|
+
* @returns The Poseidon hash as a bigint
|
|
37
|
+
* @throws If arity is not 2-6 or inputs are out of range
|
|
38
|
+
*/
|
|
39
|
+
export function poseidonHash(...inputs) {
|
|
40
|
+
const arity = inputs.length;
|
|
41
|
+
if (arity < 2 || arity > 6) {
|
|
42
|
+
throw new Error(`poseidonHash: unsupported arity ${arity} (must be 2-6)`);
|
|
43
|
+
}
|
|
44
|
+
for (let i = 0; i < inputs.length; i++) {
|
|
45
|
+
if (inputs[i] < 0n || inputs[i] >= BN254_FIELD_ORDER) {
|
|
46
|
+
throw new Error(`poseidonHash: input[${i}] out of BN254 field range`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const fn = hashFns[arity];
|
|
50
|
+
return fn(inputs);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Poseidon hash for EdDSA verification: H(R8.x, R8.y, A.x, A.y, msg)
|
|
54
|
+
* This is the exact hash used inside Noir's eddsa_poseidon_verify.
|
|
55
|
+
*/
|
|
56
|
+
export function poseidonHashEdDSA(r8x, r8y, ax, ay, msg) {
|
|
57
|
+
return poseidonHash(r8x, r8y, ax, ay, msg);
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=poseidon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"poseidon.js","sourceRoot":"","sources":["../../../sdk/src/poseidon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpD,iCAAiC;AACjC,MAAM,CAAC,MAAM,iBAAiB,GAAG,8EAA8E,CAAC;AAEhH,MAAM,OAAO,GAAiD;IAC5D,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC;IAChC,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC;IAChC,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC;IAChC,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC;IAChC,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC;CACjC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,GAAG,MAAgB;IAC9C,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;IAC5B,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,mCAAmC,KAAK,gBAAgB,CAAC,CAAC;IAC5E,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,MAAM,CAAC,CAAC,CAAC,IAAI,iBAAiB,EAAE,CAAC;YACrD,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,4BAA4B,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;IAED,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IAC1B,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC;AACpB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,GAAW,EACX,GAAW,EACX,EAAU,EACV,EAAU,EACV,GAAW;IAEX,OAAO,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proof request/response protocol for REPUTRANS.
|
|
3
|
+
*
|
|
4
|
+
* Defines the types an Arbiter uses to request proofs from a Provar,
|
|
5
|
+
* and the response format the Provar returns.
|
|
6
|
+
*/
|
|
7
|
+
export type PredicateOperator = 'gte' | 'lte';
|
|
8
|
+
export interface Predicate {
|
|
9
|
+
/** The credential field name to check. */
|
|
10
|
+
field: string;
|
|
11
|
+
/** Comparison operator: gte (>=) or lte (<=). */
|
|
12
|
+
operator: PredicateOperator;
|
|
13
|
+
/** The threshold value for comparison. */
|
|
14
|
+
threshold: bigint;
|
|
15
|
+
}
|
|
16
|
+
export interface ProofRequest {
|
|
17
|
+
/** Expected credential type (e.g. "ReputationCredential"). */
|
|
18
|
+
credentialType: string;
|
|
19
|
+
/** Field names the Provar must disclose (revealed to Arbiter). */
|
|
20
|
+
disclosedFields: string[];
|
|
21
|
+
/** Range predicates the Provar must satisfy. */
|
|
22
|
+
predicates: Predicate[];
|
|
23
|
+
/** Optional context for nullifier computation (replay prevention). */
|
|
24
|
+
nullifierContext?: string;
|
|
25
|
+
/** Optional: issuer public key the Arbiter trusts. */
|
|
26
|
+
trustedIssuerPubKey?: {
|
|
27
|
+
x: string;
|
|
28
|
+
y: string;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export interface ProofResponse {
|
|
32
|
+
/** The ZK proof bytes. */
|
|
33
|
+
proof: Uint8Array;
|
|
34
|
+
/** Public inputs to the circuit (hex strings). */
|
|
35
|
+
publicInputs: string[];
|
|
36
|
+
/** Values of disclosed fields. */
|
|
37
|
+
disclosedValues: Record<string, unknown>;
|
|
38
|
+
/** Nullifier for replay prevention (if requested). */
|
|
39
|
+
nullifier?: string;
|
|
40
|
+
/** Proof generation time in milliseconds. */
|
|
41
|
+
generationTimeMs?: number;
|
|
42
|
+
}
|
|
43
|
+
export declare class ProofRequestError extends Error {
|
|
44
|
+
constructor(message: string);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Validate a proof request has well-formed structure.
|
|
48
|
+
*/
|
|
49
|
+
export declare function validateProofRequest(req: ProofRequest): void;
|
|
50
|
+
/**
|
|
51
|
+
* Create a simple proof request for field disclosure only.
|
|
52
|
+
*/
|
|
53
|
+
export declare function createDisclosureRequest(credentialType: string, fields: string[], nullifierContext?: string): ProofRequest;
|
|
54
|
+
/**
|
|
55
|
+
* Create a proof request with range predicates.
|
|
56
|
+
*/
|
|
57
|
+
export declare function createRangeRequest(credentialType: string, predicates: Predicate[], disclosedFields?: string[], nullifierContext?: string): ProofRequest;
|
|
58
|
+
//# sourceMappingURL=proof-request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proof-request.d.ts","sourceRoot":"","sources":["../../../sdk/src/proof-request.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,KAAK,CAAC;AAE9C,MAAM,WAAW,SAAS;IACxB,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,MAAM,WAAW,YAAY;IAC3B,8DAA8D;IAC9D,cAAc,EAAE,MAAM,CAAC;IACvB,kEAAkE;IAClE,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,gDAAgD;IAChD,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,sEAAsE;IACtE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sDAAsD;IACtD,mBAAmB,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAChD;AAID,MAAM,WAAW,aAAa;IAC5B,0BAA0B;IAC1B,KAAK,EAAE,UAAU,CAAC;IAClB,kDAAkD;IAClD,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,kCAAkC;IAClC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAID,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,OAAO,EAAE,MAAM;CAI5B;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CAkC5D;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,MAAM,EAAE,EAChB,gBAAgB,CAAC,EAAE,MAAM,GACxB,YAAY,CAOd;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,SAAS,EAAE,EACvB,eAAe,GAAE,MAAM,EAAO,EAC9B,gBAAgB,CAAC,EAAE,MAAM,GACxB,YAAY,CAOd"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proof request/response protocol for REPUTRANS.
|
|
3
|
+
*
|
|
4
|
+
* Defines the types an Arbiter uses to request proofs from a Provar,
|
|
5
|
+
* and the response format the Provar returns.
|
|
6
|
+
*/
|
|
7
|
+
// -- Validation --
|
|
8
|
+
export class ProofRequestError extends Error {
|
|
9
|
+
constructor(message) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.name = 'ProofRequestError';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Validate a proof request has well-formed structure.
|
|
16
|
+
*/
|
|
17
|
+
export function validateProofRequest(req) {
|
|
18
|
+
if (!req.credentialType || typeof req.credentialType !== 'string') {
|
|
19
|
+
throw new ProofRequestError('credentialType is required');
|
|
20
|
+
}
|
|
21
|
+
if (!Array.isArray(req.disclosedFields)) {
|
|
22
|
+
throw new ProofRequestError('disclosedFields must be an array');
|
|
23
|
+
}
|
|
24
|
+
if (!Array.isArray(req.predicates)) {
|
|
25
|
+
throw new ProofRequestError('predicates must be an array');
|
|
26
|
+
}
|
|
27
|
+
for (const pred of req.predicates) {
|
|
28
|
+
if (!pred.field || typeof pred.field !== 'string') {
|
|
29
|
+
throw new ProofRequestError('Each predicate must have a field name');
|
|
30
|
+
}
|
|
31
|
+
if (pred.operator !== 'gte' && pred.operator !== 'lte') {
|
|
32
|
+
throw new ProofRequestError(`Invalid operator: ${pred.operator} (must be gte or lte)`);
|
|
33
|
+
}
|
|
34
|
+
if (typeof pred.threshold !== 'bigint') {
|
|
35
|
+
throw new ProofRequestError(`Predicate threshold must be a bigint`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Disclosed fields and predicate fields should not overlap
|
|
39
|
+
const disclosed = new Set(req.disclosedFields);
|
|
40
|
+
for (const pred of req.predicates) {
|
|
41
|
+
if (disclosed.has(pred.field)) {
|
|
42
|
+
throw new ProofRequestError(`Field "${pred.field}" is both disclosed and has a predicate - this leaks information`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Create a simple proof request for field disclosure only.
|
|
48
|
+
*/
|
|
49
|
+
export function createDisclosureRequest(credentialType, fields, nullifierContext) {
|
|
50
|
+
return {
|
|
51
|
+
credentialType,
|
|
52
|
+
disclosedFields: fields,
|
|
53
|
+
predicates: [],
|
|
54
|
+
nullifierContext,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Create a proof request with range predicates.
|
|
59
|
+
*/
|
|
60
|
+
export function createRangeRequest(credentialType, predicates, disclosedFields = [], nullifierContext) {
|
|
61
|
+
return {
|
|
62
|
+
credentialType,
|
|
63
|
+
disclosedFields,
|
|
64
|
+
predicates,
|
|
65
|
+
nullifierContext,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=proof-request.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proof-request.js","sourceRoot":"","sources":["../../../sdk/src/proof-request.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA6CH,mBAAmB;AAEnB,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAC1C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAiB;IACpD,IAAI,CAAC,GAAG,CAAC,cAAc,IAAI,OAAO,GAAG,CAAC,cAAc,KAAK,QAAQ,EAAE,CAAC;QAClE,MAAM,IAAI,iBAAiB,CAAC,4BAA4B,CAAC,CAAC;IAC5D,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,iBAAiB,CAAC,kCAAkC,CAAC,CAAC;IAClE,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,iBAAiB,CAAC,6BAA6B,CAAC,CAAC;IAC7D,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;QAClC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAClD,MAAM,IAAI,iBAAiB,CAAC,uCAAuC,CAAC,CAAC;QACvE,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,KAAK,KAAK,IAAI,IAAI,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;YACvD,MAAM,IAAI,iBAAiB,CAAC,qBAAqB,IAAI,CAAC,QAAQ,uBAAuB,CAAC,CAAC;QACzF,CAAC;QACD,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;YACvC,MAAM,IAAI,iBAAiB,CAAC,sCAAsC,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,2DAA2D;IAC3D,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC/C,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;QAClC,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,iBAAiB,CACzB,UAAU,IAAI,CAAC,KAAK,kEAAkE,CACvF,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CACrC,cAAsB,EACtB,MAAgB,EAChB,gBAAyB;IAEzB,OAAO;QACL,cAAc;QACd,eAAe,EAAE,MAAM;QACvB,UAAU,EAAE,EAAE;QACd,gBAAgB;KACjB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,cAAsB,EACtB,UAAuB,EACvB,kBAA4B,EAAE,EAC9B,gBAAyB;IAEzB,OAAO;QACL,cAAc;QACd,eAAe;QACf,UAAU;QACV,gBAAgB;KACjB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proof generation for REPUTRANS Provars.
|
|
3
|
+
*
|
|
4
|
+
* Supports both browser (WASM) and Node.js environments via
|
|
5
|
+
* @noir-lang/noir_js and @noir-lang/backend_barretenberg.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* const prover = await createProver(circuitJson);
|
|
9
|
+
* const response = await prover.generateProof(credential, privateKey, request);
|
|
10
|
+
* await prover.destroy();
|
|
11
|
+
*/
|
|
12
|
+
import { type VerifiableCredential } from './vc-parser.js';
|
|
13
|
+
import type { ProofRequest, ProofResponse } from './proof-request.js';
|
|
14
|
+
export interface CompiledCircuit {
|
|
15
|
+
bytecode: string;
|
|
16
|
+
abi: {
|
|
17
|
+
parameters: Array<{
|
|
18
|
+
name: string;
|
|
19
|
+
type: {
|
|
20
|
+
kind: string;
|
|
21
|
+
};
|
|
22
|
+
visibility: string;
|
|
23
|
+
}>;
|
|
24
|
+
};
|
|
25
|
+
[key: string]: unknown;
|
|
26
|
+
}
|
|
27
|
+
export interface Prover {
|
|
28
|
+
/** Generate a ZK proof for a credential against a proof request. */
|
|
29
|
+
generateProof(credential: VerifiableCredential, issuerPrivateKey: bigint, request: ProofRequest, masterSecret: bigint): Promise<ProofResponse>;
|
|
30
|
+
/** Destroy the prover and free WASM resources. */
|
|
31
|
+
destroy(): Promise<void>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Create a prover instance from a compiled circuit JSON.
|
|
35
|
+
* Auto-detects browser vs Node.js environment.
|
|
36
|
+
*/
|
|
37
|
+
export declare function createProver(circuit: CompiledCircuit): Promise<Prover>;
|
|
38
|
+
//# sourceMappingURL=prover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prover.d.ts","sourceRoot":"","sources":["../../../sdk/src/prover.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,EAAwB,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEjF,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGtE,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE;QACH,UAAU,EAAE,KAAK,CAAC;YAChB,IAAI,EAAE,MAAM,CAAC;YACb,IAAI,EAAE;gBAAE,IAAI,EAAE,MAAM,CAAA;aAAE,CAAC;YACvB,UAAU,EAAE,MAAM,CAAC;SACpB,CAAC,CAAC;KACJ,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,MAAM;IACrB,oEAAoE;IACpE,aAAa,CACX,UAAU,EAAE,oBAAoB,EAChC,gBAAgB,EAAE,MAAM,EACxB,OAAO,EAAE,YAAY,EACrB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,aAAa,CAAC,CAAC;IAE1B,kDAAkD;IAClD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CA+F5E"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proof generation for REPUTRANS Provars.
|
|
3
|
+
*
|
|
4
|
+
* Supports both browser (WASM) and Node.js environments via
|
|
5
|
+
* @noir-lang/noir_js and @noir-lang/backend_barretenberg.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* const prover = await createProver(circuitJson);
|
|
9
|
+
* const response = await prover.generateProof(credential, privateKey, request);
|
|
10
|
+
* await prover.destroy();
|
|
11
|
+
*/
|
|
12
|
+
import { sign } from './eddsa.js';
|
|
13
|
+
import { encodeCredential } from './encoder.js';
|
|
14
|
+
import { extractSubjectFields } from './vc-parser.js';
|
|
15
|
+
import { computeNullifier, contextToField } from './identity.js';
|
|
16
|
+
/**
|
|
17
|
+
* Create a prover instance from a compiled circuit JSON.
|
|
18
|
+
* Auto-detects browser vs Node.js environment.
|
|
19
|
+
*/
|
|
20
|
+
export async function createProver(circuit) {
|
|
21
|
+
// Dynamic imports for environment compatibility
|
|
22
|
+
const { Noir } = await import('@noir-lang/noir_js');
|
|
23
|
+
const { BarretenbergBackend } = await import('@noir-lang/backend_barretenberg');
|
|
24
|
+
const backend = new BarretenbergBackend(circuit);
|
|
25
|
+
const noir = new Noir(circuit);
|
|
26
|
+
return {
|
|
27
|
+
async generateProof(credential, issuerPrivateKey, request, masterSecret) {
|
|
28
|
+
const startTime = Date.now();
|
|
29
|
+
// 1. Encode credential fields into Merkle tree
|
|
30
|
+
const fields = extractSubjectFields(credential);
|
|
31
|
+
const encoded = encodeCredential(fields);
|
|
32
|
+
// 2. Sign the credential root with issuer key
|
|
33
|
+
const { signature, publicKey } = sign(issuerPrivateKey, encoded.merkleRoot);
|
|
34
|
+
// 3. Resolve field indices for disclosure and predicates
|
|
35
|
+
const disclosedIdx = resolveFieldIndex(encoded, request.disclosedFields[0] ?? '');
|
|
36
|
+
const predicateField = request.predicates[0];
|
|
37
|
+
const rangeIdx = predicateField
|
|
38
|
+
? resolveFieldIndex(encoded, predicateField.field)
|
|
39
|
+
: 0;
|
|
40
|
+
// 4. Compute nullifier if requested
|
|
41
|
+
let nullifier;
|
|
42
|
+
let nullifierValue = 0n;
|
|
43
|
+
if (request.nullifierContext) {
|
|
44
|
+
const ctxField = contextToField(request.nullifierContext);
|
|
45
|
+
nullifierValue = computeNullifier(masterSecret, ctxField);
|
|
46
|
+
nullifier = '0x' + nullifierValue.toString(16);
|
|
47
|
+
}
|
|
48
|
+
// 5. Build circuit inputs matching composite/src/main.nr
|
|
49
|
+
const inputs = {
|
|
50
|
+
// Signature verification
|
|
51
|
+
pub_key_x: publicKey.x.toString(),
|
|
52
|
+
pub_key_y: publicKey.y.toString(),
|
|
53
|
+
signature_r8_x: signature.r8.x.toString(),
|
|
54
|
+
signature_r8_y: signature.r8.y.toString(),
|
|
55
|
+
signature_s: signature.s.toString(),
|
|
56
|
+
msg: encoded.merkleRoot.toString(),
|
|
57
|
+
// Field disclosure
|
|
58
|
+
credential_root: encoded.merkleRoot.toString(),
|
|
59
|
+
disclosed_field_value: encoded.fieldValues[disclosedIdx].toString(),
|
|
60
|
+
disclosed_field_index: disclosedIdx.toString(),
|
|
61
|
+
disclosed_merkle_path: encoded.merklePaths[disclosedIdx].siblings.map(String),
|
|
62
|
+
disclosed_path_indices: encoded.merklePaths[disclosedIdx].indices.map(String),
|
|
63
|
+
// Range proof
|
|
64
|
+
range_field_value: predicateField
|
|
65
|
+
? encoded.fieldValues[rangeIdx].toString()
|
|
66
|
+
: '0',
|
|
67
|
+
range_field_index: rangeIdx.toString(),
|
|
68
|
+
range_merkle_path: encoded.merklePaths[rangeIdx].siblings.map(String),
|
|
69
|
+
range_path_indices: encoded.merklePaths[rangeIdx].indices.map(String),
|
|
70
|
+
range_threshold: predicateField
|
|
71
|
+
? predicateField.threshold.toString()
|
|
72
|
+
: '0',
|
|
73
|
+
range_comparison_type: predicateField
|
|
74
|
+
? (predicateField.operator === 'gte' ? '0' : '1')
|
|
75
|
+
: '0',
|
|
76
|
+
};
|
|
77
|
+
// 6. Generate proof
|
|
78
|
+
const { witness } = await noir.execute(inputs);
|
|
79
|
+
const proof = await backend.generateProof(witness);
|
|
80
|
+
// 7. Build disclosed values
|
|
81
|
+
const disclosedValues = {};
|
|
82
|
+
for (const fieldName of request.disclosedFields) {
|
|
83
|
+
disclosedValues[fieldName] = fields[fieldName];
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
proof: proof.proof,
|
|
87
|
+
publicInputs: proof.publicInputs,
|
|
88
|
+
disclosedValues,
|
|
89
|
+
nullifier,
|
|
90
|
+
generationTimeMs: Date.now() - startTime,
|
|
91
|
+
};
|
|
92
|
+
},
|
|
93
|
+
async destroy() {
|
|
94
|
+
await backend.destroy?.();
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Resolve a field name to its leaf index in the encoded credential.
|
|
100
|
+
*/
|
|
101
|
+
function resolveFieldIndex(encoded, fieldName) {
|
|
102
|
+
const idx = encoded.fieldNames.indexOf(fieldName);
|
|
103
|
+
if (idx < 0) {
|
|
104
|
+
throw new Error(`Unknown credential field "${fieldName}". Available fields: ${encoded.fieldNames.join(', ')}`);
|
|
105
|
+
}
|
|
106
|
+
return idx;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=prover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prover.js","sourceRoot":"","sources":["../../../sdk/src/prover.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* W3C Verifiable Credential parser for REPUTRANS.
|
|
3
|
+
*
|
|
4
|
+
* Parses W3C VC JSON-LD into typed objects, validates required fields,
|
|
5
|
+
* and extracts credentialSubject for downstream encoding.
|
|
6
|
+
*/
|
|
7
|
+
export interface CredentialProof {
|
|
8
|
+
type: string;
|
|
9
|
+
created?: string;
|
|
10
|
+
verificationMethod?: string;
|
|
11
|
+
proofPurpose?: string;
|
|
12
|
+
proofValue?: string;
|
|
13
|
+
[key: string]: unknown;
|
|
14
|
+
}
|
|
15
|
+
export interface CredentialSubject {
|
|
16
|
+
id?: string;
|
|
17
|
+
[key: string]: unknown;
|
|
18
|
+
}
|
|
19
|
+
export interface VerifiableCredential {
|
|
20
|
+
'@context': string | string[];
|
|
21
|
+
type: string | string[];
|
|
22
|
+
issuer: string | {
|
|
23
|
+
id: string;
|
|
24
|
+
[key: string]: unknown;
|
|
25
|
+
};
|
|
26
|
+
issuanceDate?: string;
|
|
27
|
+
credentialSubject: CredentialSubject;
|
|
28
|
+
proof: CredentialProof;
|
|
29
|
+
id?: string;
|
|
30
|
+
expirationDate?: string;
|
|
31
|
+
[key: string]: unknown;
|
|
32
|
+
}
|
|
33
|
+
export declare class VCParseError extends Error {
|
|
34
|
+
constructor(message: string);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Parse a W3C Verifiable Credential from a JSON string or object.
|
|
38
|
+
* Validates all required fields are present.
|
|
39
|
+
*/
|
|
40
|
+
export declare function parseVC(input: string | Record<string, unknown>): VerifiableCredential;
|
|
41
|
+
/**
|
|
42
|
+
* Extract credentialSubject fields as a flat key-value map.
|
|
43
|
+
* Nested objects are JSON-stringified.
|
|
44
|
+
*/
|
|
45
|
+
export declare function extractSubjectFields(vc: VerifiableCredential): Record<string, string>;
|
|
46
|
+
/**
|
|
47
|
+
* Get the issuer ID string regardless of issuer format.
|
|
48
|
+
*/
|
|
49
|
+
export declare function getIssuerId(vc: VerifiableCredential): string;
|
|
50
|
+
//# sourceMappingURL=vc-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vc-parser.d.ts","sourceRoot":"","sources":["../../../sdk/src/vc-parser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC9B,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,KAAK,EAAE,eAAe,CAAC;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAID,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM;CAI5B;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,oBAAoB,CA0DrF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAWrF;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,oBAAoB,GAAG,MAAM,CAG5D"}
|