mirror of
https://github.com/selfxyz/self.git
synced 2026-02-19 02:24:25 -05:00
Feat/sumsub (#1654)
* fix: circuits and contracts * feat: add reverse ofac logic * feat: add onlyRole modifiers to functions * style: replace onlyOwner reference in comment code to role-based access * test: unskip and update governance tests for access control * test: fix PCR0 setup in kyc test --------- Co-authored-by: Evi Nova <tranquil_flow@protonmail.com>
This commit is contained in:
@@ -50,7 +50,7 @@ template VC_AND_DISCLOSE_KYC(
|
||||
var country_length = COUNTRY_LENGTH();
|
||||
var id_number_length = ID_NUMBER_LENGTH();
|
||||
var idNumberIdx = ID_NUMBER_INDEX();
|
||||
var compressed_bit_len = max_length/2;
|
||||
var compressed_bit_len = max_length % 2 == 1 ? (max_length - 1)/2 : max_length / 2;
|
||||
|
||||
signal input data_padded[max_length];
|
||||
signal input compressed_disclose_sel[2];
|
||||
@@ -86,14 +86,14 @@ template VC_AND_DISCLOSE_KYC(
|
||||
low_bits.in <== compressed_disclose_sel[0];
|
||||
|
||||
// Convert disclose_sel_high (next 133 bits) to bit array
|
||||
component high_bits = Num2Bits(compressed_bit_len);
|
||||
component high_bits = Num2Bits(max_length - compressed_bit_len);
|
||||
high_bits.in <== compressed_disclose_sel[1];
|
||||
|
||||
// Combine the bit arrays (little-endian format)
|
||||
for(var i = 0; i < compressed_bit_len; i++){
|
||||
disclose_sel[i] <== low_bits.out[i];
|
||||
}
|
||||
for(var i = 0; i < compressed_bit_len; i++){
|
||||
for(var i = 0; i < max_length - compressed_bit_len; i++){
|
||||
disclose_sel[compressed_bit_len + i] <== high_bits.out[i];
|
||||
}
|
||||
|
||||
@@ -135,3 +135,14 @@ template VC_AND_DISCLOSE_KYC(
|
||||
signal output nullifier <== Poseidon(2)([secret, scope]);
|
||||
signal output attestation_id <== 4;
|
||||
}
|
||||
|
||||
component main {
|
||||
public [
|
||||
scope,
|
||||
merkle_root,
|
||||
ofac_name_dob_smt_root,
|
||||
ofac_name_yob_smt_root,
|
||||
user_identifier,
|
||||
current_date
|
||||
]
|
||||
} = VC_AND_DISCLOSE_KYC(40, 64, 64, 33);
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "./vc_and_disclose_kyc.circom";
|
||||
|
||||
component main {
|
||||
public [
|
||||
scope,
|
||||
merkle_root,
|
||||
ofac_name_dob_smt_root,
|
||||
ofac_name_yob_smt_root,
|
||||
user_identifier,
|
||||
current_date,
|
||||
attestation_id
|
||||
]
|
||||
} = VC_AND_DISCLOSE_KYC(40, 64, 64, 33);
|
||||
@@ -11,6 +11,8 @@ template REGISTER_KYC() {
|
||||
var max_length = KYC_MAX_LENGTH();
|
||||
var country_length = COUNTRY_LENGTH();
|
||||
var id_number_length = ID_NUMBER_LENGTH();
|
||||
var id_type_length = ID_TYPE_LENGTH();
|
||||
var id_type_index = ID_TYPE_INDEX();
|
||||
var idNumberIdx = ID_NUMBER_INDEX();
|
||||
|
||||
signal input data_padded[max_length];
|
||||
@@ -49,7 +51,22 @@ template REGISTER_KYC() {
|
||||
for (var i = 0; i < id_number_length; i++) {
|
||||
id_num[i] <== data_padded[idNumberIdx + i];
|
||||
}
|
||||
signal output nullifier <== PackBytesAndPoseidon(id_number_length)(id_num);
|
||||
|
||||
signal nullifier_inputs[6 + id_number_length + id_type_length];
|
||||
|
||||
nullifier_inputs[0] <== 115; //s
|
||||
nullifier_inputs[1] <== 117; //u
|
||||
nullifier_inputs[2] <== 109; //m
|
||||
nullifier_inputs[3] <== 115; //s
|
||||
nullifier_inputs[4] <== 117; //u
|
||||
nullifier_inputs[5] <== 98; //b
|
||||
for (var i = 0; i < id_number_length; i++) {
|
||||
nullifier_inputs[i + 6] <== id_num[i];
|
||||
}
|
||||
for (var i = 0; i < id_type_length; i++) {
|
||||
nullifier_inputs[i + 6 + id_number_length] <== data_padded[id_type_index + i];
|
||||
}
|
||||
signal output nullifier <== PackBytesAndPoseidon(6 + id_number_length + id_type_length)(nullifier_inputs);
|
||||
signal output commitment <== Poseidon(2)([secret, msg_hasher.out]);
|
||||
|
||||
signal output pubkey_hash <== Poseidon(2)([verifyIdCommSig.Ax, verifyIdCommSig.Ay]);
|
||||
|
||||
@@ -72,20 +72,12 @@ function PHONE_NUMBER_LENGTH() {
|
||||
return 12;
|
||||
}
|
||||
|
||||
function DOCUMENT_INDEX() {
|
||||
function GENDER_INDEX() {
|
||||
return PHONE_NUMBER_INDEX() + PHONE_NUMBER_LENGTH();
|
||||
}
|
||||
|
||||
function DOCUMENT_LENGTH() {
|
||||
return 32;
|
||||
}
|
||||
|
||||
function GENDER_INDEX() {
|
||||
return DOCUMENT_INDEX() + DOCUMENT_LENGTH();
|
||||
}
|
||||
|
||||
function GENDER_LENGTH() {
|
||||
return 6;
|
||||
return 1;
|
||||
}
|
||||
|
||||
function ADDRESS_INDEX() {
|
||||
|
||||
@@ -18,7 +18,7 @@ CIRCUITS=(
|
||||
# "vc_and_disclose:20:true"
|
||||
# "vc_and_disclose_id:20:true"
|
||||
# "vc_and_disclose_aadhaar:20:true"
|
||||
"vc_and_disclose_selfrica:17:true"
|
||||
"vc_and_disclose_kyc:17:true"
|
||||
)
|
||||
|
||||
build_circuits "$CIRCUIT_TYPE" "$OUTPUT_DIR" "${CIRCUITS[@]}"
|
||||
|
||||
@@ -15,7 +15,7 @@ OUTPUT_DIR="build/${CIRCUIT_TYPE}"
|
||||
# Define circuits and their configurations
|
||||
# format: name:poweroftau:build_flag
|
||||
CIRCUITS=(
|
||||
"register_selfrica:15:true"
|
||||
"register_kyc:15:true"
|
||||
)
|
||||
|
||||
build_circuits "$CIRCUIT_TYPE" "$OUTPUT_DIR" "${CIRCUITS[@]}"
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -154,6 +154,33 @@ describe('VC_AND_DISCLOSE KYC Circuit Tests', () => {
|
||||
deepEqual(ofac_results, ['\x00', '\x00']);
|
||||
});
|
||||
|
||||
it('should return 0 for an OFAC person with reverse', async function () {
|
||||
this.timeout(0);
|
||||
const input = generateKycDiscloseInput(
|
||||
true,
|
||||
namedob_smt,
|
||||
nameyob_smt,
|
||||
tree as any,
|
||||
true,
|
||||
'0',
|
||||
'1234567890',
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
true,
|
||||
'1234',
|
||||
true
|
||||
);
|
||||
const witness = await circuit.calculateWitness(input);
|
||||
await circuit.checkConstraints(witness);
|
||||
|
||||
const revealedData_packed = await getRevealedDataPacked(witness);
|
||||
const revealedDataUnpacked = unpackReveal(revealedData_packed, 'id');
|
||||
const ofac_results = revealedDataUnpacked.slice(maxLength, maxLength + 2);
|
||||
|
||||
deepEqual(ofac_results, ['\x00', '\x00']);
|
||||
});
|
||||
|
||||
it('should return 1 for a non OFAC person', async function () {
|
||||
this.timeout(0);
|
||||
const input = generateKycDiscloseInput(
|
||||
@@ -193,7 +220,6 @@ describe('VC_AND_DISCLOSE KYC Circuit Tests', () => {
|
||||
'DOB',
|
||||
'PHOTO_HASH',
|
||||
'PHONE_NUMBER',
|
||||
'DOCUMENT',
|
||||
'GENDER',
|
||||
'ADDRESS',
|
||||
];
|
||||
@@ -251,7 +277,6 @@ describe('VC_AND_DISCLOSE KYC Circuit Tests', () => {
|
||||
'DOB',
|
||||
'PHOTO_HASH',
|
||||
'PHONE_NUMBER',
|
||||
'DOCUMENT',
|
||||
'GENDER',
|
||||
'ADDRESS',
|
||||
];
|
||||
|
||||
@@ -5,7 +5,7 @@ import { packBytesAndPoseidon } from '@selfxyz/common/utils/hash';
|
||||
import { poseidon2 } from 'poseidon-lite';
|
||||
import { generateMockKycRegisterInput } from '@selfxyz/common/utils/kyc/generateInputs.js';
|
||||
import { KycRegisterInput } from '@selfxyz/common/utils/kyc/types';
|
||||
import { KYC_ID_NUMBER_INDEX, KYC_ID_NUMBER_LENGTH } from '@selfxyz/common/utils/kyc/constants';
|
||||
import { KYC_ID_NUMBER_INDEX, KYC_ID_NUMBER_LENGTH, KYC_ID_TYPE_INDEX, KYC_ID_TYPE_LENGTH } from '@selfxyz/common/utils/kyc/constants';
|
||||
|
||||
describe('REGISTER KYC Circuit Tests', () => {
|
||||
let circuit: any;
|
||||
@@ -15,7 +15,7 @@ describe('REGISTER KYC Circuit Tests', () => {
|
||||
this.timeout(0);
|
||||
input = await generateMockKycRegisterInput(null, true, undefined);
|
||||
circuit = await wasmTester(
|
||||
path.join(__dirname, '../../circuits/register/instances/register_selfrica.circom'),
|
||||
path.join(__dirname, '../../circuits/register/instances/register_kyc.circom'),
|
||||
{
|
||||
verbose: true,
|
||||
logOutput: true,
|
||||
@@ -42,7 +42,8 @@ describe('REGISTER KYC Circuit Tests', () => {
|
||||
KYC_ID_NUMBER_INDEX,
|
||||
KYC_ID_NUMBER_INDEX + KYC_ID_NUMBER_LENGTH
|
||||
);
|
||||
const nullifier = packBytesAndPoseidon(idnumber.map((x) => Number(x)));
|
||||
const nullifierInputs = [...'sumsub'.split('').map((x) => x.charCodeAt(0)), ...idnumber, ...input.data_padded.slice(KYC_ID_TYPE_INDEX, KYC_ID_TYPE_INDEX + KYC_ID_TYPE_LENGTH)];
|
||||
const nullifier = packBytesAndPoseidon(nullifierInputs);
|
||||
const commitment = poseidon2([
|
||||
input.secret,
|
||||
packBytesAndPoseidon(input.data_padded.map((x) => Number(x))),
|
||||
|
||||
Reference in New Issue
Block a user