poseidon function

BigInt poseidon(
  1. List<BigInt> _inputs,
  2. Map<String, dynamic> opt
)

Implementation

BigInt poseidon(List<BigInt> _inputs, Map<String, dynamic> opt) {
  List<BigInt> inputs = _inputs.map((i) => i).toList();
  if (inputs.isEmpty) {
    throw ArgumentError('poseidon-lite: Not enough inputs');
  }
  if (inputs.length > N_ROUNDS_P.length) {
    throw ArgumentError('poseidon-lite: Too many inputs');
  }

  final t = inputs.length + 1;
  const nRoundsF = 8;
  final nRoundsP = N_ROUNDS_P[t - 2];

  final List<BigInt> C = (opt['C'] as List).map((e) => e as BigInt).toList();
  final List<List<BigInt>> M = (opt['M'] as List)
      .map((value) => (value as List).map((e) => e as BigInt).toList())
      .toList();

  if (M.length != t) {
    throw ArgumentError(
        'poseidon-lite: Incorrect M length, expected $t got ${M.length}');
  }

  List<BigInt> state = [BigInt.zero, ...inputs];
  for (int x = 0; x < nRoundsF + nRoundsP; x++) {
    for (int y = 0; y < state.length; y++) {
      state[y] = state[y] + C[x * t + y];
      if (x < nRoundsF ~/ 2 || x >= nRoundsF ~/ 2 + nRoundsP) {
        state[y] = pow5(state[y]);
      } else if (y == 0) {
        state[y] = pow5(state[y]);
      }
    }
    state = mix(state, M);
  }
  return state[0];
}