Circomlib assert fail on simple MimcSponge hash - hash

I am playing around with circom and circomlib.
I am using a simple mimcsponge hashing circuit and seeing if I can create a correct input through javascript frontend.
The circuit I am running
template sponge_test() {
signal input l;
signal input r;
signal input o;
// instantiate - 2 inputs 220 rounds of hashing and 1 output
component hasher = MiMCSponge(2, 220, 1);
// signals in hasher
hasher.ins[0] <== l;
hasher.ins[1] <== r;
// addition constant
hasher.k <== 0;
o === hasher.outs[0];
}
component main = sponge_test();
In my javascript front end I am importing circomlib
import { buildMimcSponge } from 'circomlibjs';
function toHexString(byteArray) {
return Array.from(byteArray, function(byte) {
return ('0' + (byte & 0xFF).toString(16)).slice(-2);
}).join('')
}
export async function getProof(message) {
var hasher = await buildMimcSponge();
var h = hasher.multiHash([BigInt("0x3"), BigInt("0x4")]);
// returns byte array
console.log(h);
// back to hexstring
console.log(toHexString(h));
}
I then create an input.json that looks like this:
{
"l": "0x3",
"r": "0x4",
"o": "0x690f48aba976f2786371b7fa3e941df623e96329e0570dc610f59b7fcfa94723"
}
Which includes the values I used for the input of the hashing and the output I got from printing the hex value, and then run the following script
# Compile the circuit
circom ${CIRCUIT}.circom --r1cs --wasm --sym --c
# Generate the witness.wtns
node ${CIRCUIT}_js/generate_witness.js ${CIRCUIT}_js/${CIRCUIT}.wasm input.json ${CIRCUIT}_js/witness.wtns
And I get the error that the assert (o===hasher.outs[0]) fails.
Now, I know that that mimcsponge circuit uses 220 rounds as well in the javascript implementation of circomlib by looking at the node lib, where else could I be reaching inconsistent results for the hashing?

So I found that reading the has is done using the following. I believe it is because it is specific to the elliptic curves being used.
hasher.F.toString(h, 16);
This produces the expected result which gets accepted by the circuit.
If anyone has further insights, I would be happy to understand it further.

Related

Pedersen circom/circomlibjs inconsistency?

As a unit test for a larger use case, I am checking that indeed the pedersen hash I am doing in the frontend aligns with the expected hash done through a circom circuit. I am using a simple assert in the circuit and generating a witness and am feeding both the hashed and unhashed values to the circuit, recreating the hash to make sure that it goes through.
I am running a Pedersen hash in my frontend using circomlibjs. As a unit test, I have. a circuit with a simple assert that check whether the results from my frontend line up with the pedersen hash in the circom circuit.
The circuit I am using:
include "../node_modules/circomlib/circuits/bitify.circom";
include "../node_modules/circomlib/circuits/pedersen.circom";
template check() {
signal input unhashed;
signal input hashed;
signal output createdHash[2];
component hasher = Pedersen(256);
component unhashedBits = Num2Bits(256);
unhashedBits.in <== unhashed;
for (var i = 0; i < 256; i++){
hasher.in[i] <== unhashedBits.out[i];
}
createdHash[0] <== hasher.out[0];
createdHash[1] <== hasher.out[1];
hashed === createdHash[1];
}
component main = check();
In the frontend, I am running the following,
import { buildPedersenHash } from 'circomlibjs';
export function buff2hex(buff) {
function i2hex(i) {
return ('0' + i.toString(16)).slice(-2);
}
return '0x' + Array.from(buff).map(i2hex).join('');
}
const secret = (new TextEncoder(32)).encode("Hello");
var pedersen = await buildPedersenHash();
var h = pedersen.hash(secret);
console.log(buff2hex(secret));
console.log(buff2hex(h));
The values that are printed are:
0x48656c6c6f
0x0e90d7d613ab8b5ea7f4f8bc537db6bb0fa2e5e97bbac1c1f609ef9e6a35fd8b
Which are consistent with the test done here.
So I then create an input.json file which looks as follows,
{
"unhashed": "0x48656c6c6f",
"hashed": "0x0e90d7d613ab8b5ea7f4f8bc537db6bb0fa2e5e97bbac1c1f609ef9e6a35fd8b"
}
And lastly run the following script to create a witness, in the hopes that the assert will go through.
# Compile the circuit
circom ${CIRCUIT}.circom --r1cs --wasm --sym --c
# Generate the witness.wtns
node ${CIRCUIT}_js/generate_witness.js ${CIRCUIT}_js/${CIRCUIT}.wasm input.json ${CIRCUIT}_js/witness.wtns
However, I keep getting an assert error,
Error: Error: Assert Failed.
Error in template check_11 line: 26
Which describes the assert in the circuit, so I assume there is an inconsistency in the hash.
I am new to circom so any insights would be greatly appreciated!
For anyone who stumbles across this, it happens that the cause of issue is endianess. The issue was fixed by converting the unhashed to little endian in the input, I am not sure as to where exactly the problem is, but seems like the hasher reads it as big endian on the frontend but the input is expected little endian (or vice verse).
As I have managed to patch up a fix for this at the moment, I will stop investigating, but implore anyone who understand this further to give a better explanation.

ranges::views::generate have generator function signal end of range

I'd like to have a generator that terminates, like python, but I can't tell from ranges::views::generate's interface if this is supported.
You can roll it by hand easily enough:
https://godbolt.org/z/xcGz6657r although it's probably better to use a coroutine generator if you have one available.
You can return an optional in the generator, and stop taking elements when a std::nullopt is generated with views::take_while
auto out = ranges::views::generate(
[i = 0]() mutable -> std::optional<int>
{
if (i > 3)
return std::nullopt;
return { i++ };
})
| ranges::views::take_while([](auto opt){ return opt.has_value();})
;

Where does a variable in a match arm in a loop come from?

I am trying to implement an HTTP client in Rust using this as a starting point. I was sent to this link by the rust-lang.org site via one of their rust-by-example suggestions in their TcpStream page. I'm figuring out how to read from a TcpStream. I'm trying to follow this code:
fn handle_client(mut stream: TcpStream) {
// read 20 bytes at a time from stream echoing back to stream
loop {
let mut read = [0; 1028];
match stream.read(&mut read) {
Ok(n) => {
if n == 0 {
// connection was closed
break;
}
stream.write(&read[0..n]).unwrap();
}
Err(err) => {
panic!(err);
}
}
}
}
Where does the n variable come from? What exactly is it? The author says it reads 20 bytes at a time; where is this coming from?
I haven't really tried anything yet because I want to understand before I do.
I strongly encourage you to read the documentation for the tools you use. In this case, The match Control Flow Operator from The Rust Programming Language explains what you need to know.
From the Patterns that Bind to Values section:
In the match expression for this code, we add a variable called state to the pattern that matches values of the variant Coin::Quarter. When a Coin::Quarter matches, the state variable will bind to the value of that quarter’s state. Then we can use state in the code for that arm, like so:
fn value_in_cents(coin: Coin) -> u8 {
match coin {
Coin::Penny => 1,
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter(state) => {
println!("State quarter from {:?}!", state);
25
},
}
}
If we were to call value_in_cents(Coin::Quarter(UsState::Alaska)), coin would be Coin::Quarter(UsState::Alaska). When we compare that value with each of the match arms, none of them match until we reach Coin::Quarter(state). At that point, the binding for state will be the value UsState::Alaska. We can then use that binding in the println! expression, thus getting the inner state value out of the Coin enum variant for Quarter.
There is an entire chapter about the pattern matching syntax available and where it can be used.
Figured it out, this is what's happening:
match stream.read(&mut read) {
This line is telling the software to pass stream.read(&mut read) to Ok(n) because stream.read returns the number of bytes read. I'm still not sure why they specify 20 bytes at a time as being read.

Creating a numpy python string array with pybind11

I am trying to modify a numpy string array from c++ with pybind11. The code i am using has the following structure:
py::array_t<py::str> process_array(py::array_t<py::str> input);
PYBIND11_EMBEDDED_MODULE(fast_calc, m) {
m.def("process_array", process_array);
}
py::array_t<py::str> process_array(py::array_t<py::str> input) {
auto buf = input.request();
cout << &buf;
return input;
}
The problem i face is this error message:
pybind11/numpy.h:1114:19: error: static assertion failed: Attempt to use a non-POD or unimplemented POD type as a numpy dtype
static_assert(is_pod_struct::value, "Attempt to use a non-POD or unimplemented POD type as a numpy dtype");
Not sure whats the catch. In python you can create numpy string arrays so what am i doing wrong?
Thanks.
Fixed length strings are supported in pybind11 (tested on v2.2.3, CentOS7, python3.6.5) by using the pybind11::array_t< std::array<char, N> > or char[N] type. Likely you'll want to pad out the string with null values just in case, as the standard pitfalls of C-style strings apply (e.g. N-1 useable characters). I prefer working with std::array as it doesn't decay to a char* without calling .data() making your intentions clearer to other readers.
So some psuedocode would look like this for a vector of 16 byte strings:
using np_str_t = std::array<char, 16>;
pybind11::array_t<np_str_t> cstring_array(vector.size());
np_str_t* array_of_cstr_ptr = reinterpret_cast<np_str_t*>(cstring_array.request().ptr);
for(const auto & s : vector)
{
std::strncpy(array_of_cstr_ptr->data(), s.data(), array_of_cstr_ptr->size());
array_of_cstr_ptr++;
}
return cstring_array; //numpy array back to python code
And then in python:
array([b'ABC', b'XYZ'], dtype='|S16')

Receiving data in node.js

I am having a java program send data to me over a specific socket to my node.js application. I want to be able to obtain all of the data, which is information from a SQlite database, and send it off to something else.
I've found something like the following can work but it seems to be unreliable as data is missing and sometimes it doesn't even show up.
stream.addListener('data', function(data){
buffer.write(data.toString());
});
on a side note, I need the socket to stay open so I can't call the "end" event.
I really don't have any attachment to stream.addListener so i can use something else if it works how i want. Basically what i'm asking is, What is the most effective way to obtain data from a socket using node.js?
P.S. thank you for your time
The data event is not guaranteed to have all the data sent to it in one go. You'll need to build up a buffer over multiple events and watch for delimiters of some kind (newlines, null characters, whatever you feel). Here's an example from a project where I'm parsing data from IRC (converted from CoffeeScript); parseData is the event handler for the data event (e.g. socket.on('data', this.parseData);):
IrcConnection.prototype.parseData = function(data) {
var line, lines, i;
data = data.replace("\r\n", "\n");
this.buffer += data;
lines = this.buffer.split("\n");
this.buffer = "";
/* Put the last line back in the buffer if it was incomplete */
if (lines[lines.length - 1] !== '') {
this.buffer = lines[lines.length - 1];
}
/* Remove the final \n or incomplete line from the array */
lines = lines.splice(0, lines.length - 1);
for (i = 0; i < lines.length; i++) {
line = lines[i];
this.emit('raw', line);
}
};