Skip to content

Commit

Permalink
Merge pull request #444 from 0xPolygonID/refactor/drop_native_poseidon
Browse files Browse the repository at this point in the history
Added env and auth claim retrieval cache.
  • Loading branch information
5eeman authored Oct 10, 2024
2 parents c9198bb + 8857c86 commit 6375ccb
Show file tree
Hide file tree
Showing 21 changed files with 251 additions and 621 deletions.
7 changes: 0 additions & 7 deletions ios/Classes/SwiftPolygonIdSdkPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,9 @@ public class SwiftPolygonIdSdkPlugin: NSObject, FlutterPlugin {

public static func dummyMethodToEnforceBundling() {
// LibBabyjubjub bindings
pack_signature("16727755406458403965916091816756284515992637653800319054951151706132152331811672775540645840396591609181675628451599263765380031");
unpack_signature("16727755406458403965916091816756284515992637653800319054951151706132152331811672775540645840396591609181675628451599263765380031");
pack_point("17777552123799933955779906779655732241715742912184938656739573121738514868268", "2626589144620713026669568689430873010625803728049924121243784502389097019475");
unpack_point("53b81ed5bffe9545b54016234682e7b2f699bd42a5e9eae27ff4051bc698ce85");
prv2pub("0001020304050607080900010203040506070809000102030405060708090001");
poseidon_hash("");
poseidon_hash2("", "");
poseidon_hash3("", "", "");
poseidon_hash4("", "", "", "");
hash_poseidon("", "", "");
sign_poseidon("", "");
verify_poseidon("", "", "");
let str = "string"
Expand Down
16 changes: 0 additions & 16 deletions ios/Classes/libbabyjubjub.h
Original file line number Diff line number Diff line change
@@ -1,27 +1,11 @@
// NOTE: Append the lines below to ios/Classes/<your>Plugin.h

char *pack_signature(const char *signature);

char *unpack_signature(const char *compressed_signature);

char *pack_point(const char *point_x, const char *point_y);

char *unpack_point(const char *compressed_point);

char *prv2pub(const char *private_key);

char *poseidon_hash(const char *input);

char *poseidon_hash2(const char *in1, const char *in2);

char *poseidon_hash3(const char *in1, const char *in2, const char *in3);

char *poseidon_hash4(const char *in1, const char *in2, const char *in3, const char *in4);

char *hash_poseidon(const char *claims_tree,
const char *revocation_tree,
const char *roots_tree_root);

char *sign_poseidon(const char *private_key, const char *msg);

char *verify_poseidon(const char *private_key,
Expand Down
16 changes: 16 additions & 0 deletions lib/common/data/repositories/config_repository_impl.dart
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
import 'package:injectable/injectable.dart';
import 'package:polygonid_flutter_sdk/common/data/data_sources/storage_key_value_data_source.dart';
import 'package:polygonid_flutter_sdk/common/data/exceptions/env_exceptions.dart';
import 'package:polygonid_flutter_sdk/common/domain/entities/env_entity.dart';
import 'package:polygonid_flutter_sdk/common/domain/repositories/config_repository.dart';

@singleton
class ConfigRepositoryImpl implements ConfigRepository {
final StorageKeyValueDataSource _storageKeyValueDataSource;

ConfigRepositoryImpl(
this._storageKeyValueDataSource,
);

EnvEntity? _envCache;

@override
Future<EnvEntity> getEnv() {
if (_envCache != null) {
return Future.value(_envCache!);
}

return _storageKeyValueDataSource.get(key: "env").then((value) {
if (value == null) {
return Future.error(EnvNotSetException());
Expand All @@ -23,18 +31,26 @@ class ConfigRepositoryImpl implements ConfigRepository {

@override
Future<void> setEnv({required EnvEntity env}) {
_envCache = env;
return _storageKeyValueDataSource.store(key: "env", value: env.toJson());
}

String? _selectedChainIdCache;

@override
Future<String?> getSelectedChainId() {
if (_selectedChainIdCache != null) {
return Future.value(_selectedChainIdCache);
}

return _storageKeyValueDataSource.get(key: "selected_chain").then((value) {
return value;
});
}

@override
Future<void> setSelectedChainId({required String chainId}) {
_selectedChainIdCache = chainId;
return _storageKeyValueDataSource.store(
key: "selected_chain", value: chainId);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/common/domain/use_cases/get_env_use_case.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class GetEnvUseCase extends FutureUseCase<void, EnvEntity> {
@override
Future<EnvEntity> execute({dynamic param}) {
return _configRepository.getEnv().then((env) {
logger().i("[GetEnvUseCase] Current env is: $env");
logger().d("[GetEnvUseCase] Current env is: $env");

return env;
}).catchError((error) {
Expand Down
83 changes: 0 additions & 83 deletions lib/common/utils/hex_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,87 +66,4 @@ class HexUtils {

return 'hez:${base64Url.encode(finalBuffBjj.toBytes())}';
}

static Uint8List hexToBuffer(String source) {
// String (Dart uses UTF-16) to bytes
List<int> list = [];
for (var rune in source.runes) {
if (rune >= 0x10000) {
rune -= 0x10000;
int firstWord = (rune >> 10) + 0xD800;
list.add(firstWord >> 8);
list.add(firstWord & 0xFF);
int secondWord = (rune & 0x3FF) + 0xDC00;
list.add(secondWord >> 8);
list.add(secondWord & 0xFF);
} else {
list.add(rune >> 8);
list.add(rune & 0xFF);
}
}
Uint8List bytes = Uint8List.fromList(list);
return bytes;
}

/// Converts a buffer to a hexadecimal representation
///
/// @param {Uint8List} buf
///
/// @returns {String}
static String bufToHex(Uint8List buf) {
return const Utf8Decoder().convert(buf);
}

/// Poseidon hash of a generic buffer
/// @param {Uint8List} msgBuff
/// @returns {BigInt} - final hash
static BigInt hashBuffer(Uint8List msgBuff) {
const n = 31;
List<BigInt> msgArray = [];
final fullParts = (msgBuff.length / n).floor();
for (int i = 0; i < fullParts; i++) {
final v = msgBuff.sublist(n * i, n * (i + 1));
msgArray.add(Uint8ArrayUtils.bytesToBigInt(v));
}
if (msgBuff.length % n != 0) {
final v = msgBuff.sublist(fullParts * n);
msgArray.add(Uint8ArrayUtils.bytesToBigInt(v));
}
return multiHash(msgArray);
}

/// Chunks inputs in five elements and hash with Poseidon all them togheter
/// @param {Array} arr - inputs hash
/// @returns {BigInt} - final hash
static BigInt multiHash(List<BigInt> arr) {
BigInt r = BigInt.zero;
for (int i = 0; i < arr.length; i += 5) {
final fiveElems = [];
for (int j = 0; j < 5; j++) {
if (i + j < arr.length) {
fiveElems.add(arr[i + j]);
} else {
fiveElems.add(BigInt.zero);
}
}
//Pointer<Uint8> ptr =
// Uint8ArrayUtils.toPointer(Uint8List.fromList(fiveElems as List<int>));
//final ph = eddsaBabyJub.hashPoseidon(ptr);
//r = F.add(r, ph);
}
// TODO: fix this
return BigInt.zero;
//return F.normalize(r);
}

/// Mask and shift a BigInt
///
/// @param {BigInt} num - Input number
/// @param {int} origin - Initial bit
/// @param {int} len - Bit length of the mask
/// @returns {BigInt} Scalar
static BigInt extract(BigInt num, int origin, int len) {
BigInt mask = (BigInt.one << len) - BigInt.one;
return (num >> origin) & mask;
}
}
15 changes: 15 additions & 0 deletions lib/credential/data/data_sources/local_claim_data_source.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import 'dart:convert';

import 'package:injectable/injectable.dart';

import '../../../constants.dart';
import 'lib_pidcore_credential_data_source.dart';

@singleton
class LocalClaimDataSource {
LibPolygonIdCoreCredentialDataSource _libPolygonIdCoreCredentialDataSource;

final _cache = <String, List<String>>{};

LocalClaimDataSource(this._libPolygonIdCoreCredentialDataSource);

Future<List<String>> getAuthClaim({
Expand All @@ -14,13 +19,23 @@ class LocalClaimDataSource {
}) {
final nonce = authClaimNonce ?? DEFAULT_AUTH_CLAIM_NONCE;

final cacheKey = _cacheKey(publicKey.toString(), nonce);
if (_cache.containsKey(cacheKey)) {
return Future.value(_cache[cacheKey]!);
}

String authClaimSchema = AUTH_CLAIM_SCHEMA;
String authClaim = _libPolygonIdCoreCredentialDataSource.issueClaim(
schema: authClaimSchema,
nonce: nonce,
publicKey: publicKey,
);
List<String> children = List.from(jsonDecode(authClaim));

_cache[cacheKey] = children;

return Future.value(children);
}
}

String _cacheKey(String publicKey, String nonce) => publicKey + "_" + nonce;
47 changes: 24 additions & 23 deletions lib/iden3comm/authenticate.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ import 'package:polygonid_flutter_sdk/iden3comm/domain/exceptions/iden3comm_exce
import 'package:polygonid_flutter_sdk/iden3comm/domain/exceptions/jwz_exceptions.dart';
import 'package:polygonid_flutter_sdk/iden3comm/domain/use_cases/generate_iden3comm_proof_use_case.dart';
import 'package:polygonid_flutter_sdk/iden3comm/domain/use_cases/get_iden3message_use_case.dart';
import 'package:polygonid_flutter_sdk/identity/data/data_sources/lib_babyjubjub_data_source.dart';
import 'package:polygonid_flutter_sdk/identity/data/data_sources/lib_pidcore_identity_data_source.dart';
import 'package:polygonid_flutter_sdk/identity/data/data_sources/wallet_data_source.dart';
import 'package:polygonid_flutter_sdk/identity/data/dtos/circuit_type.dart';
Expand Down Expand Up @@ -88,6 +87,8 @@ import 'package:polygonid_flutter_sdk/proof/gist_proof_cache.dart';
import 'package:polygonid_flutter_sdk/proof/infrastructure/proof_generation_stream_manager.dart';
import 'package:polygonid_flutter_sdk/proof/libs/polygonidcore/pidcore_proof.dart';
import 'package:polygonid_flutter_sdk/sdk/di/injector.dart';
import 'package:poseidon/constants/p1.dart';
import 'package:poseidon/poseidon.dart';
import 'package:sembast/sembast.dart';
import 'package:uuid/uuid.dart';
import 'package:web3dart/crypto.dart';
Expand Down Expand Up @@ -1027,11 +1028,9 @@ class Authenticate {
// Endianness
BigInt endian = Uint8ArrayUtils.leBuff2int(sha);

String qNormalized = endian.qNormalize().toString();
BigInt qNormalized = endian.qNormalize();

var libBabyJubJub = getItSdk<LibBabyJubJubDataSource>();

String authChallenge = await libBabyJubJub.hashPoseidon(qNormalized);
String authChallenge = poseidon1([qNormalized]).toString();

String signature = await signMessage(
privateKey: privateKeyBytes,
Expand Down Expand Up @@ -1140,28 +1139,30 @@ class Authenticate {
publicKey: publicKey,
);
authClaim = List.from(jsonDecode(issuedAuthClaim));
var libBabyJubJub = getItSdk<LibBabyJubJubDataSource>();
String hashIndex = await libBabyJubJub.hashPoseidon4(
authClaim[0],
authClaim[1],
authClaim[2],
authClaim[3],
);
String hashValue = await libBabyJubJub.hashPoseidon4(
authClaim[4],
authClaim[5],
authClaim[6],
authClaim[7],
);
String hashClaimNode = await libBabyJubJub.hashPoseidon3(
hashIndex, hashValue, BigInt.one.toString());
BigInt hashIndex = poseidon4([
BigInt.parse(authClaim[0]),
BigInt.parse(authClaim[1]),
BigInt.parse(authClaim[2]),
BigInt.parse(authClaim[3]),
]);
BigInt hashValue = poseidon4([
BigInt.parse(authClaim[4]),
BigInt.parse(authClaim[5]),
BigInt.parse(authClaim[6]),
BigInt.parse(authClaim[7]),
]);
BigInt hashClaimNode = poseidon3([
hashIndex,
hashValue,
BigInt.one,
]);
NodeEntity authClaimNode = NodeEntity(
children: [
HashEntity.fromBigInt(BigInt.parse(hashIndex)),
HashEntity.fromBigInt(BigInt.parse(hashValue)),
HashEntity.fromBigInt(hashIndex),
HashEntity.fromBigInt(hashValue),
HashEntity.fromBigInt(BigInt.one),
],
hash: HashEntity.fromBigInt(BigInt.parse(hashClaimNode)),
hash: HashEntity.fromBigInt(hashClaimNode),
type: NodeType.leaf,
);

Expand Down
10 changes: 4 additions & 6 deletions lib/iden3comm/data/repositories/iden3comm_repository_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,20 @@ import 'package:polygonid_flutter_sdk/iden3comm/domain/entities/proof/response/i
import 'package:polygonid_flutter_sdk/iden3comm/domain/exceptions/iden3comm_exceptions.dart';
import 'package:polygonid_flutter_sdk/iden3comm/domain/repositories/iden3comm_repository.dart';
import 'package:polygonid_flutter_sdk/iden3comm/domain/use_cases/get_iden3message_use_case.dart';
import 'package:polygonid_flutter_sdk/identity/data/data_sources/lib_babyjubjub_data_source.dart';
import 'package:polygonid_flutter_sdk/identity/data/mappers/q_mapper.dart';
import 'package:polygonid_flutter_sdk/identity/domain/entities/identity_entity.dart';
import 'package:polygonid_flutter_sdk/proof/data/dtos/gist_mtproof_entity.dart';
import 'package:polygonid_flutter_sdk/proof/data/dtos/mtproof_dto.dart';
import 'package:polygonid_flutter_sdk/proof/data/mappers/gist_mtproof_mapper.dart';
import 'package:poseidon/poseidon.dart';
import 'package:poseidon/poseidon/poseidon.dart';
import 'package:uuid/uuid.dart';

class Iden3commRepositoryImpl extends Iden3commRepository {
final Iden3MessageDataSource _iden3messageDataSource;
final RemoteIden3commDataSource _remoteIden3commDataSource;
final LibPolygonIdCoreIden3commDataSource
_libPolygonIdCoreIden3commDataSource;
final LibBabyJubJubDataSource
_libBabyJubJubDataSource; // TODO move bjj DS to common
final AuthResponseMapper _authResponseMapper;
final AuthProofMapper _authProofMapper;
final GistMTProofMapper _gistProofMapper;
Expand All @@ -54,7 +53,6 @@ class Iden3commRepositoryImpl extends Iden3commRepository {
this._iden3messageDataSource,
this._remoteIden3commDataSource,
this._libPolygonIdCoreIden3commDataSource,
this._libBabyJubJubDataSource,
this._authResponseMapper,
this._authProofMapper,
this._gistProofMapper,
Expand Down Expand Up @@ -174,9 +172,9 @@ class Iden3commRepositoryImpl extends Iden3commRepository {
}

@override
Future<String> getChallenge({required String message}) {
Future<String> getChallenge({required String message}) async {
final q = _qMapper.mapFrom(message);
return _libBabyJubJubDataSource.hashPoseidon(q);
return poseidon1([BigInt.parse(q)]).toString();
}

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ class CheckProfileAndDidCurrentEnvUseCase
);

@override
Future<void> execute(
{required CheckProfileAndDidCurrentEnvParam param}) async {
Future<void> execute({
required CheckProfileAndDidCurrentEnvParam param,
}) async {
try {
final timestamp = DateTime.now().millisecondsSinceEpoch;
// check if profile is valid, it will throw an exception if not
await _checkProfileValidityUseCase.execute(
param: CheckProfileValidityParam(profileNonce: param.profileNonce));
Expand Down Expand Up @@ -69,8 +71,8 @@ class CheckProfileAndDidCurrentEnvUseCase
);
}

logger().i(
"[CheckProfileAndDidCurrentEnvUseCase] Profile ${param.profileNonce} and private key are valid for current env");
logger().d(
"[CheckProfileAndDidCurrentEnvUseCase] Profile ${param.profileNonce} and private key are valid for current env in ${DateTime.now().millisecondsSinceEpoch - timestamp} ms");
_stacktraceManager.addTrace(
"[CheckProfileAndDidCurrentEnvUseCase] Profile ${param.profileNonce} and private key are valid for current env");
} on PolygonIdSDKException catch (_) {
Expand Down
Loading

0 comments on commit 6375ccb

Please sign in to comment.