Addvances in the verifier script of 09/24/24

This commit is contained in:
thomaslavaur 2024-09-25 09:40:17 +02:00
parent 788a57a6e7
commit 0635a277d7
4 changed files with 172 additions and 59 deletions

View File

@ -28,7 +28,6 @@ thiserror.workspace = true
tracing.workspace = true
rayon = { version = "1.10.0", optional = true }
serde = { version = "1.0", features = ["derive"] }
light-poseidon = {path = "../../../../../save/rust/snarks/light-poseidon/light-poseidon"}
crypto-bigint = "0.5.5"
ark-serialize = "0.4.0"
serde_json = "1.0.116"

View File

@ -118,7 +118,7 @@ pub fn verify<MC: MerkleChannel>(
let composition_oods_eval = extract_composition_eval(sampled_oods_values).map_err(|_| {
VerificationError::InvalidStructure("Unexpected sampled_values structure".to_string())
})?;
println!("composition_oods_eval = {:?}",composition_oods_eval);
if composition_oods_eval
// Compute
!= components.eval_composition_polynomial_at_point(

View File

@ -400,6 +400,7 @@ mod tests {
#[cfg(not(target_arch = "wasm32"))]
use crate::core::vcs::poseidon_bls_merkle::PoseidonBLSMerkleChannel;
use crate::core::ColumnVec;
use crate::core::fields::qm31::QM31;
use crate::examples::wide_fibonacci::{generate_trace, FibInput, WideFibonacciComponent};
const FIB_SEQUENCE_LENGTH: usize = 100;
@ -604,6 +605,7 @@ mod tests {
)
.unwrap();
_ = pretty_save_poseidon_bls_proof(&proof);
println!(" 0 1 0 0 = {:?}",QM31::from_u32_unchecked(0,1,0,0));
// Verify.
let verifier_channel = &mut PoseidonBLSChannel::default();

View File

@ -174,7 +174,7 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 128,
"id": "67a09953",
"metadata": {},
"outputs": [],
@ -195,7 +195,33 @@
" remainder = cur % shift\n",
" cur = quotient\n",
" u32s.append(M31(remainder))\n",
" return u32s"
" return u32s\n",
"\n",
"def draw_random_bytes(digest, n_sent):\n",
" shift = 1 << 8\n",
" cur = int(draw_felt252(digest, n_sent))\n",
" byte = []\n",
" for i in range(31):\n",
" quotient = cur // shift\n",
" remainder = cur % shift\n",
" cur = quotient\n",
" byte.append(remainder)\n",
" return byte\n",
"\n",
"def hash_node(has_children, left, right, column_values):\n",
" n_column_blocks = ceil(len(column_values) / 8.0);\n",
" values = []\n",
" if has_children:\n",
" values.append(left)\n",
" values.append(right)\n",
" padding_length = 8 * n_column_blocks - len(column_values)\n",
" padded_values = column_values + [F(0) for i in range(padding_length)]\n",
" for i in range(int(len(padded_values) / 8)):\n",
" word = F(0)\n",
" for j in range(8):\n",
" word = word * F(2**31) + F(padded_values[i*8+j])\n",
" values.append(word)\n",
" return poseidon_hash_many_bls(values)"
]
},
{
@ -296,7 +322,7 @@
},
{
"cell_type": "code",
"execution_count": 10,
"execution_count": 312,
"id": "d9371b02",
"metadata": {},
"outputs": [],
@ -326,83 +352,169 @@
"point = oods_point\n",
"mask_values = proof[\"sampled_values_0\"] + proof[\"sampled_values_1\"]\n",
"\n",
"accumulator = random_coeff\n",
"\n",
"\n",
"\n",
"# Evaluate random point on the vanishing polynomial of the coset\n",
"evaluation = point.x\n",
"for i in range(5):\n",
" evaluation = CirclePoint.double_x(evaluation)\n",
"evaluation_inverse = evaluation ** (-1)"
"evaluation_inverse = evaluation ** (-1)\n",
"\n",
"# Compute evaluation using the mask values\n",
"accumulator = QM31(0)\n",
"a = QM31([mask_values[0][:2],mask_values[0][2:4]])\n",
"b = QM31([mask_values[1][:2],mask_values[1][2:4]])\n",
"for i in range(len(proof[\"sampled_values_0\"])-2):\n",
" c = QM31([mask_values[2+i][:2],mask_values[2+i][2:4]])\n",
" accumulator = (c - (a**2 + b**2))*evaluation_inverse + accumulator * random_coeff\n",
" a = b\n",
" b = c\n",
"\n",
"expected_value = QM31([proof[\"sampled_values_1\"][0][:2],proof[\"sampled_values_1\"][0][2:4]]) + QM31([proof[\"sampled_values_1\"][1][:2],proof[\"sampled_values_1\"][1][2:4]]) * QM31([[0,1],[0,0]]) + QM31([proof[\"sampled_values_1\"][2][:2],proof[\"sampled_values_1\"][2][2:4]]) * QM31([[0,0],[1,0]]) + QM31([proof[\"sampled_values_1\"][3][:2],proof[\"sampled_values_1\"][3][2:4]]) * QM31([[0,0],[0,1]])\n",
"\n",
"assert(expected_value == accumulator)\n",
"\n",
"\n",
"####FRI part\n",
"# Fiat-Shamir\n",
"shift = F(1 << 31)\n",
"res = [digest]\n",
"for i in range(len(mask_values) / 2):\n",
" cur = F(0)\n",
" for j in range(2):\n",
" for k in range(4):\n",
" cur = cur * shift + F(mask_values[2*i+j][k])\n",
" res.append(cur)\n",
"digest = poseidon_hash_many_bls(res)\n",
"random_coeff = QM31([draw_base_felts(digest,0)[:2],draw_base_felts(digest,0)[2:4]])\n",
"\n",
"# Verify commitment stage\n",
"circle_poly_alpha = QM31([draw_base_felts(digest,1)[:2],draw_base_felts(digest,1)[2:4]])\n",
"folding_alpha = []\n",
"for i in range(6):\n",
" digest = poseidon_hash_bls(digest,proof[\"inner_commitment_\"+str(i)])\n",
" folding_alpha.append(QM31([draw_base_felts(digest,0)[:2],draw_base_felts(digest,0)[2:4]]))\n",
"last_layer_poly = QM31([proof[\"coeffs\"][:2],proof[\"coeffs\"][2:4]])\n",
"\n",
"#Check proof of work\n",
"res = [digest]\n",
"cur = F(0)\n",
"for i in range(4):\n",
" cur = cur * shift + F(proof[\"coeffs\"][i])\n",
"res.append(cur)\n",
"digest = poseidon_hash_many_bls(res)\n",
"digest = poseidon_hash_bls(digest, proof[\"proof of work\"])\n",
"# The first 5 bits following the first 1 must be 0 for proof of work\n",
"for i in range(5):\n",
" assert(bin(digest)[3+i] == '0')\n",
"\n",
"# Compute openings positions\n",
"querries = []\n",
"max_querry = (1<<8)-1\n",
"random_bytes = draw_random_bytes(digest,0)\n",
"# The number of required querries is 3 so we need 3*8 bytes wich is enough with the 31 bytes of random_bytes\n",
"for i in range(3):\n",
" querry_bits = int().from_bytes(random_bytes[i*4:i*4+4],byteorder=\"little\")\n",
" querries.append(querry_bits & max_querry)\n",
"positions = []\n",
"# For each collumn\n",
"for i in range(2):\n",
" # For each querry\n",
" for j in range(3):\n",
" positions.append(querries[j] >> (1+i))\n",
"positions_sav = positions.copy()\n",
"\n",
"\n",
"#Verify decommitments (this part must be simplified repeting duplicated inputs)\n",
"# First tree\n",
"nodes = {}\n",
"for i in range(6):\n",
" leaf = []\n",
" for j in range(100):\n",
" leaf.append(M31(proof[\"queried_values_0\"][j][i]))\n",
" nodes[\"level_0_node_\"+str(positions[i//2] // 2 * 2 + i % 2) ] = hash_node(false,0,0,leaf)\n",
"counter = 0\n",
"for level in range(7):\n",
" for i in range(3):\n",
" if \"level_\"+str(level)+\"_node_\"+str(positions[len(positions)-3] * 2) in nodes:\n",
" lhs = nodes[\"level_\"+str(level)+\"_node_\"+str(positions[len(positions)-3] * 2)]\n",
" else:\n",
" lhs = F(proof[\"decommitment_0\"][counter])\n",
" counter += 1\n",
" if \"level_\"+str(level)+\"_node_\"+str(positions[len(positions) - 3] * 2 + 1) in nodes:\n",
" rhs = nodes[\"level_\"+str(level)+\"_node_\"+str(positions[len(positions) - 3] * 2 + 1)]\n",
" else:\n",
" rhs = F(proof[\"decommitment_0\"][counter])\n",
" counter += 1\n",
" nodes[\"level_\"+str(level+1)+\"_node_\"+str(positions[len(positions)-3])] = hash_node(true,lhs,rhs,[])\n",
" positions.append(positions[len(positions)-3] // 2)\n",
"assert(nodes[\"level_7_node_0\"] == F(proof[\"commitments\"][0]))\n",
"\n",
"#Second tree\n",
"positions = positions_sav\n",
"for i in range(len(positions)):\n",
" positions[i] = positions[i] * 2\n",
"nodes = {}\n",
"for i in range(6):\n",
" leaf = []\n",
" for j in range(4):\n",
" leaf.append(M31(proof[\"queried_values_1\"][j][i]))\n",
" nodes[\"level_0_node_\"+str(positions[i//2] // 2 * 2 + i % 2) ] = hash_node(false,0,0,leaf)\n",
"counter = 0\n",
"for level in range(8):\n",
" for i in range(3):\n",
" if \"level_\"+str(level)+\"_node_\"+str(positions[len(positions)-3] * 2) in nodes:\n",
" lhs = nodes[\"level_\"+str(level)+\"_node_\"+str(positions[len(positions)-3] * 2)]\n",
" else:\n",
" lhs = F(proof[\"decommitment_1\"][counter])\n",
" counter += 1\n",
" if \"level_\"+str(level)+\"_node_\"+str(positions[len(positions) - 3] * 2 + 1) in nodes:\n",
" rhs = nodes[\"level_\"+str(level)+\"_node_\"+str(positions[len(positions) - 3] * 2 + 1)]\n",
" else:\n",
" rhs = F(proof[\"decommitment_1\"][counter])\n",
" counter += 1\n",
" nodes[\"level_\"+str(level+1)+\"_node_\"+str(positions[len(positions)-3])] = hash_node(true,lhs,rhs,[])\n",
" if level == 0:\n",
" nodes[\"level_1_node_\"+str(positions[len(positions)-3] + 1)] = hash_node(true,nodes[\"level_0_node_\"+str((positions[len(positions)-3] + 1)* 2)],nodes[\"level_0_node_\"+str((positions[len(positions)-3] + 1)* 2 + 1)],[])\n",
" positions.append(positions[len(positions)-3] // 2)\n",
"assert(nodes[\"level_8_node_0\"] == F(proof[\"commitments\"][1]))\n",
"\n",
"\n",
"# Check querries answer\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3adb682e",
"id": "56e4c016",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 11,
"id": "59b44767",
"execution_count": null,
"id": "6b89599c",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(1001989877*i + 1100649138)*u + 462165474*i + 673026348"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"evaluation_inverse"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "7790a0f9",
"metadata": {},
"outputs": [
{
"ename": "AttributeError",
"evalue": "'PolynomialQuotientRing_field_with_category.element_class' object has no attribute 'double'",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m/tmp/ipykernel_10017/940279797.py\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[0ma\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mQM31\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mInteger\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mInteger\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mInteger\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mInteger\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[0mb\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mQM31\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mInteger\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m2129160320\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mInteger\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1109509513\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mInteger\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m787887008\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mInteger\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1676461964\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[0ma\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdouble\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0mb\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdouble\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[1;32m/usr/lib/python3/dist-packages/sage/structure/element.pyx\u001b[0m in \u001b[0;36msage.structure.element.Element.__getattr__ (build/cythonized/sage/structure/element.c:4827)\u001b[1;34m()\u001b[0m\n\u001b[0;32m 492\u001b[0m \u001b[0mAttributeError\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'LeftZeroSemigroup_with_category.element_class'\u001b[0m \u001b[0mobject\u001b[0m \u001b[0mhas\u001b[0m \u001b[0mno\u001b[0m \u001b[0mattribute\u001b[0m \u001b[1;34m'blah_blah'\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 493\u001b[0m \"\"\"\n\u001b[1;32m--> 494\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgetattr_from_category\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mname\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 495\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 496\u001b[0m \u001b[0mcdef\u001b[0m \u001b[0mgetattr_from_category\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mname\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32m/usr/lib/python3/dist-packages/sage/structure/element.pyx\u001b[0m in \u001b[0;36msage.structure.element.Element.getattr_from_category (build/cythonized/sage/structure/element.c:4939)\u001b[1;34m()\u001b[0m\n\u001b[0;32m 505\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 506\u001b[0m \u001b[0mcls\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mP\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_abstract_element_class\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 507\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mgetattr_from_other_class\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcls\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mname\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 508\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 509\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m__dir__\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;32m/usr/lib/python3/dist-packages/sage/cpython/getattr.pyx\u001b[0m in \u001b[0;36msage.cpython.getattr.getattr_from_other_class (build/cythonized/sage/cpython/getattr.c:2636)\u001b[1;34m()\u001b[0m\n\u001b[0;32m 354\u001b[0m \u001b[0mdummy_error_message\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcls\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mtype\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 355\u001b[0m \u001b[0mdummy_error_message\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mname\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mname\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 356\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mAttributeError\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdummy_error_message\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 357\u001b[0m \u001b[0mcdef\u001b[0m \u001b[0mPyObject\u001b[0m\u001b[1;33m*\u001b[0m \u001b[0mattr\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0minstance_getattr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcls\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mname\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 358\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mattr\u001b[0m \u001b[1;32mis\u001b[0m \u001b[0mNULL\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;31mAttributeError\u001b[0m: 'PolynomialQuotientRing_field_with_category.element_class' object has no attribute 'double'"
]
}
],
"source": [
"a = QM31([[1,0],[0,0]])\n",
"b = QM31([[2129160320,1109509513],[787887008,1676461964]])\n",
"a.double() + b.double()\n"
]
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "5f95a975",
"id": "e486cb3a",
"metadata": {},
"outputs": [],
"source": [
"\n",
"[[\"1\",\"0\",\"0\",\"0\"],\n",
"\t\t[\"2129160320\",\"1109509513\",\"787887008\",\"1676461964\"],\n",
"\t\t[\"262908602\",\"915488457\",\"1893945291\",\"1774327476\"]"
]
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "85dd52b3",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {