Skip to content

Commit 5c6c2ca

Browse files
authored
chore: Use simple "flat" CRS. (AztecProtocol#3748)
There's no need for us to have such a convoluted set of transcripts for our CRS in a complicated format. This: * Uses a single 6GB "flat" CRS with no header data in the ignition s3 bucket, in normalised big-endian form. * Allows us to use our normal deserialization functions for the fields, as opposed to specific custom SRS reading code. * Means we can now download, without complexity, any size CRS we need. * Changes names to eg `bn254_g1.dat` so doesn't conflict with old cache. * Get's rid of `size` file and just directly analyses file sizes. It doesn't address: * The new grumpkin CRS that arrived yesterday. Someone else can tackle that one. We also need to figure out how to generate a real one. Another trusted setup??....
1 parent 9f3d972 commit 5c6c2ca

File tree

8 files changed

+108
-112
lines changed

8 files changed

+108
-112
lines changed

barretenberg/cpp/src/barretenberg/bb/file_io.hpp

+20-7
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,42 @@
11
#pragma once
22
#include <barretenberg/common/log.hpp>
3+
#include <cstdint>
34
#include <fstream>
45
#include <ios>
56
#include <vector>
67

7-
inline std::vector<uint8_t> read_file(const std::string& filename, size_t bytes = 0)
8+
inline size_t get_file_size(std::string const& filename)
89
{
910
// Open the file in binary mode and move to the end.
1011
std::ifstream file(filename, std::ios::binary | std::ios::ate);
1112
if (!file) {
12-
throw std::runtime_error("Unable to open file: " + filename);
13+
return 0;
1314
}
1415

16+
file.seekg(0, std::ios::end);
17+
return (size_t)file.tellg();
18+
}
19+
20+
inline std::vector<uint8_t> read_file(const std::string& filename, size_t bytes = 0)
21+
{
1522
// Get the file size.
16-
std::streamsize size = bytes == 0 ? (std::streamsize)file.tellg() : (std::streamsize)bytes;
23+
auto size = get_file_size(filename);
1724
if (size <= 0) {
1825
throw std::runtime_error("File is empty or there's an error reading it: " + filename);
1926
}
2027

28+
auto to_read = bytes == 0 ? size : bytes;
29+
30+
std::ifstream file(filename, std::ios::binary);
31+
if (!file) {
32+
throw std::runtime_error("Unable to open file: " + filename);
33+
}
34+
2135
// Create a vector with enough space for the file data.
22-
std::vector<uint8_t> fileData((size_t)size);
36+
std::vector<uint8_t> fileData(to_read);
2337

24-
// Go back to the start of the file and read all its contents.
25-
file.seekg(0, std::ios::beg);
26-
file.read(reinterpret_cast<char*>(fileData.data()), size);
38+
// Read all its contents.
39+
file.read(reinterpret_cast<char*>(fileData.data()), (std::streamsize)to_read);
2740

2841
return fileData;
2942
}
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,17 @@
11
#include "get_bn254_crs.hpp"
2-
3-
// Gets the transcript URL from the BARRETENBERG_TRANSCRIPT_URL environment variable, if set.
4-
// Otherwise returns the default URL.
5-
namespace {
6-
std::string get_bn254_transcript_url()
7-
{
8-
const char* ENV_VAR_NAME = "BARRETENBERG_TRANSCRIPT_URL";
9-
const std::string DEFAULT_URL = "https://aztec-ignition.s3.amazonaws.com/MAIN%20IGNITION/monomial/transcript00.dat";
10-
11-
const char* env_url = std::getenv(ENV_VAR_NAME);
12-
13-
auto environment_variable_exists = ((env_url != nullptr) && *env_url);
14-
15-
return environment_variable_exists ? std::string(env_url) : DEFAULT_URL;
16-
}
17-
} // namespace
2+
#include "barretenberg/bb/file_io.hpp"
183

194
std::vector<uint8_t> download_bn254_g1_data(size_t num_points)
205
{
21-
size_t g1_start = 28;
22-
size_t g1_end = g1_start + num_points * 64 - 1;
6+
size_t g1_end = num_points * 64 - 1;
237

24-
std::string url = get_bn254_transcript_url();
8+
std::string url = "https://aztec-ignition.s3.amazonaws.com/MAIN%20IGNITION/flat/g1.dat";
259

26-
std::string command =
27-
"curl -s -H \"Range: bytes=" + std::to_string(g1_start) + "-" + std::to_string(g1_end) + "\" '" + url + "'";
10+
std::string command = "curl -s -H \"Range: bytes=0-" + std::to_string(g1_end) + "\" '" + url + "'";
2811

2912
auto data = exec_pipe(command);
3013
// Header + num_points * sizeof point.
31-
if (data.size() < g1_end - g1_start) {
14+
if (data.size() < g1_end) {
3215
throw std::runtime_error("Failed to download g1 data.");
3316
}
3417

@@ -37,67 +20,52 @@ std::vector<uint8_t> download_bn254_g1_data(size_t num_points)
3720

3821
std::vector<uint8_t> download_bn254_g2_data()
3922
{
40-
size_t g2_start = 28 + 5040001 * 64;
41-
size_t g2_end = g2_start + 128 - 1;
42-
43-
std::string url = get_bn254_transcript_url();
44-
45-
std::string command =
46-
"curl -s -H \"Range: bytes=" + std::to_string(g2_start) + "-" + std::to_string(g2_end) + "\" '" + url + "'";
47-
23+
std::string url = "https://aztec-ignition.s3.amazonaws.com/MAIN%20IGNITION/flat/g2.dat";
24+
std::string command = "curl -s '" + url + "'";
4825
return exec_pipe(command);
4926
}
5027

5128
std::vector<barretenberg::g1::affine_element> get_bn254_g1_data(const std::filesystem::path& path, size_t num_points)
5229
{
5330
std::filesystem::create_directories(path);
54-
std::ifstream size_file(path / "size");
55-
size_t size = 0;
56-
if (size_file) {
57-
size_file >> size;
58-
size_file.close();
59-
}
60-
if (size >= num_points) {
61-
vinfo("using cached crs at: ", path);
62-
auto data = read_file(path / "g1.dat", 28 + num_points * 64);
31+
32+
auto g1_path = path / "bn254_g1.dat";
33+
size_t g1_file_size = get_file_size(g1_path);
34+
35+
if (g1_file_size >= num_points * 64 && g1_file_size % 64 == 0) {
36+
vinfo("using cached crs of size ", std::to_string(g1_file_size / 64), " at ", g1_path);
37+
auto data = read_file(g1_path, g1_file_size);
6338
auto points = std::vector<barretenberg::g1::affine_element>(num_points);
64-
auto size_of_points_in_bytes = num_points * 64;
65-
barretenberg::srs::IO<curve::BN254>::read_affine_elements_from_buffer(
66-
points.data(), (char*)data.data(), size_of_points_in_bytes);
39+
for (size_t i = 0; i < num_points; ++i) {
40+
points[i] = from_buffer<barretenberg::g1::affine_element>(data, i * 64);
41+
}
6742
return points;
6843
}
6944

7045
vinfo("downloading crs...");
7146
auto data = download_bn254_g1_data(num_points);
72-
write_file(path / "g1.dat", data);
73-
74-
std::ofstream new_size_file(path / "size");
75-
if (!new_size_file) {
76-
throw std::runtime_error("Failed to open size file for writing");
77-
}
78-
new_size_file << num_points;
79-
new_size_file.close();
47+
write_file(g1_path, data);
8048

8149
auto points = std::vector<barretenberg::g1::affine_element>(num_points);
82-
barretenberg::srs::IO<curve::BN254>::read_affine_elements_from_buffer(
83-
points.data(), (char*)data.data(), data.size());
50+
for (size_t i = 0; i < num_points; ++i) {
51+
points[i] = from_buffer<barretenberg::g1::affine_element>(data, i * 64);
52+
}
8453
return points;
8554
}
8655

8756
barretenberg::g2::affine_element get_bn254_g2_data(const std::filesystem::path& path)
8857
{
8958
std::filesystem::create_directories(path);
9059

91-
try {
92-
auto data = read_file(path / "g2.dat");
93-
barretenberg::g2::affine_element g2_point;
94-
barretenberg::srs::IO<curve::BN254>::read_affine_elements_from_buffer(&g2_point, (char*)data.data(), 128);
95-
return g2_point;
96-
} catch (std::exception&) {
97-
auto data = download_bn254_g2_data();
98-
write_file(path / "g2.dat", data);
99-
barretenberg::g2::affine_element g2_point;
100-
barretenberg::srs::IO<curve::BN254>::read_affine_elements_from_buffer(&g2_point, (char*)data.data(), 128);
101-
return g2_point;
60+
auto g2_path = path / "bn254_g2.dat";
61+
size_t g2_file_size = get_file_size(g2_path);
62+
63+
if (g2_file_size == 128) {
64+
auto data = read_file(g2_path);
65+
return from_buffer<barretenberg::g2::affine_element>(data.data());
10266
}
67+
68+
auto data = download_bn254_g2_data();
69+
write_file(g2_path, data);
70+
return from_buffer<barretenberg::g2::affine_element>(data.data());
10371
}

barretenberg/cpp/src/barretenberg/bb/get_grumpkin_crs.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@ std::vector<curve::Grumpkin::AffineElement> get_grumpkin_g1_data(const std::file
4545
size_file.close();
4646
}
4747
if (size >= num_points) {
48-
vinfo("using cached crs at: ", path);
49-
auto data = read_file(path / "grumpkin_g1.dat", 28 + num_points * 64);
48+
auto file = path / "grumpkin_g1.dat";
49+
vinfo("using cached crs at: ", file);
50+
auto data = read_file(file, 28 + num_points * 64);
5051
auto points = std::vector<curve::Grumpkin::AffineElement>(num_points);
5152
auto size_of_points_in_bytes = num_points * 64;
5253
barretenberg::srs::IO<curve::Grumpkin>::read_affine_elements_from_buffer(

barretenberg/cpp/src/barretenberg/bb/main.cpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,14 @@
1919
#include <vector>
2020

2121
using namespace barretenberg;
22-
std::string CRS_PATH = "./crs";
22+
23+
std::string getHomeDir()
24+
{
25+
char* home = std::getenv("HOME");
26+
return home != nullptr ? std::string(home) : "./";
27+
}
28+
29+
std::string CRS_PATH = getHomeDir() + "/.bb-crs";
2330
bool verbose = false;
2431

2532
const std::filesystem::path current_path = std::filesystem::current_path();
@@ -441,7 +448,7 @@ int main(int argc, char* argv[])
441448
std::string proof_path = get_option(args, "-p", "./proofs/proof");
442449
std::string vk_path = get_option(args, "-k", "./target/vk");
443450
std::string pk_path = get_option(args, "-r", "./target/pk");
444-
CRS_PATH = get_option(args, "-c", "./crs");
451+
CRS_PATH = get_option(args, "-c", CRS_PATH);
445452
bool recursive = flag_present(args, "-r") || flag_present(args, "--recursive");
446453

447454
// Skip CRS initialization for any command which doesn't require the CRS.

barretenberg/cpp/src/barretenberg/ecc/fields/field2_declarations.hpp

+12
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,16 @@ template <class base_field, class Params> struct alignas(32) field2 {
138138
}
139139
};
140140

141+
template <typename B, typename base_field, typename Params> void read(B& it, field2<base_field, Params>& value)
142+
{
143+
using serialize::read;
144+
read(it, value.c0);
145+
read(it, value.c1);
146+
}
147+
template <typename B, typename base_field, typename Params> void write(B& buf, field2<base_field, Params> const& value)
148+
{
149+
using serialize::write;
150+
write(buf, value.c0);
151+
write(buf, value.c1);
152+
}
141153
} // namespace barretenberg

barretenberg/cpp/src/barretenberg/srs/c_bind.cpp

+10-10
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,18 @@
99
using namespace barretenberg;
1010

1111
/**
12-
* WARNING: The SRS is not encoded the same way as all the read/write methods encode.
13-
* Have to use the old school io functions to parse the buffers.
12+
* We are not passed a vector (length prefixed), but the buffer and num points independently.
13+
* Saves on having the generate the vector awkwardly calling side after downloading crs.
1414
*/
15-
WASM_EXPORT void srs_init_srs(uint8_t const* points_buf, uint32_t const* num_points, uint8_t const* g2_point_buf)
15+
WASM_EXPORT void srs_init_srs(uint8_t const* points_buf, uint32_t const* num_points_buf, uint8_t const* g2_point_buf)
1616
{
17-
auto points = std::vector<g1::affine_element>(ntohl(*num_points));
18-
srs::IO<curve::BN254>::read_affine_elements_from_buffer(points.data(), (char*)points_buf, points.size() * 64);
19-
20-
g2::affine_element g2_point;
21-
srs::IO<curve::BN254>::read_affine_elements_from_buffer(&g2_point, (char*)g2_point_buf, 128);
22-
23-
barretenberg::srs::init_crs_factory(points, g2_point);
17+
auto num_points = ntohl(*num_points_buf);
18+
auto g1_points = std::vector<g1::affine_element>(num_points);
19+
for (size_t i = 0; i < num_points; ++i) {
20+
g1_points[i] = from_buffer<barretenberg::g1::affine_element>(points_buf, i * 64);
21+
}
22+
auto g2_point = from_buffer<g2::affine_element>(g2_point_buf);
23+
barretenberg::srs::init_crs_factory(g1_points, g2_point);
2424
}
2525

2626
/**

barretenberg/ts/src/crs/net_crs.ts

+4-11
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,11 @@ export class NetCrs {
2121
}
2222

2323
async downloadG1Data() {
24-
const g1Start = 28;
25-
const g1End = g1Start + this.numPoints * 64 - 1;
24+
const g1End = this.numPoints * 64 - 1;
2625

27-
const response = await fetch('https://aztec-ignition.s3.amazonaws.com/MAIN%20IGNITION/monomial/transcript00.dat', {
26+
const response = await fetch('https://aztec-ignition.s3.amazonaws.com/MAIN%20IGNITION/flat/g1.dat', {
2827
headers: {
29-
Range: `bytes=${g1Start}-${g1End}`,
28+
Range: `bytes=0-${g1End}`,
3029
},
3130
cache: 'force-cache',
3231
});
@@ -38,13 +37,7 @@ export class NetCrs {
3837
* Download the G2 points data.
3938
*/
4039
async downloadG2Data() {
41-
const g2Start = 28 + 5040001 * 64;
42-
const g2End = g2Start + 128 - 1;
43-
44-
const response2 = await fetch('https://aztec-ignition.s3.amazonaws.com/MAIN%20IGNITION/monomial/transcript00.dat', {
45-
headers: {
46-
Range: `bytes=${g2Start}-${g2End}`,
47-
},
40+
const response2 = await fetch('https://aztec-ignition.s3.amazonaws.com/MAIN%20IGNITION/flat/g2.dat', {
4841
cache: 'force-cache',
4942
});
5043

barretenberg/ts/src/crs/node/index.ts

+19-17
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { NetCrs } from '../net_crs.js';
22
import { GRUMPKIN_SRS_DEV_PATH, IgnitionFilesCrs } from './ignition_files_crs.js';
33
import { mkdirSync, readFileSync, writeFileSync } from 'fs';
4-
import { readFile } from 'fs/promises';
4+
import { readFile, stat } from 'fs/promises';
55
import createDebug from 'debug';
6+
import { homedir } from 'os';
67

78
const debug = createDebug('bb.js:crs');
89

@@ -12,47 +13,48 @@ const debug = createDebug('bb.js:crs');
1213
export class Crs {
1314
constructor(public readonly numPoints: number, public readonly path: string) {}
1415

15-
static async new(numPoints: number, crsPath = './crs') {
16+
static async new(numPoints: number, crsPath = homedir() + '/.bb-crs') {
1617
const crs = new Crs(numPoints, crsPath);
1718
await crs.init();
1819
return crs;
1920
}
2021

2122
async init() {
2223
mkdirSync(this.path, { recursive: true });
23-
const size = await readFile(this.path + '/size', 'ascii').catch(() => undefined);
24-
if (size && +size >= this.numPoints) {
25-
debug(`using cached crs of size: ${size}`);
24+
25+
const g1FileSize = await stat(this.path + '/bn254_g1.dat')
26+
.then(stats => stats.size)
27+
.catch(() => 0);
28+
const g2FileSize = await stat(this.path + '/bn254_g2.dat')
29+
.then(stats => stats.size)
30+
.catch(() => 0);
31+
32+
if (g1FileSize >= this.numPoints * 64 && g1FileSize % 64 == 0 && g2FileSize == 128) {
33+
debug(`using cached crs of size: ${g1FileSize / 64}`);
2634
return;
2735
}
2836

29-
const ignitionCrs = new IgnitionFilesCrs(this.numPoints);
30-
const crs = ignitionCrs.pathExists() ? new IgnitionFilesCrs(this.numPoints) : new NetCrs(this.numPoints);
31-
if (crs instanceof NetCrs) {
32-
debug(`downloading crs of size: ${this.numPoints}`);
33-
} else {
34-
debug(`loading igntion file crs of size: ${this.numPoints}`);
35-
}
37+
debug(`downloading crs of size: ${this.numPoints}`);
38+
const crs = new NetCrs(this.numPoints);
3639
await crs.init();
37-
writeFileSync(this.path + '/size', this.numPoints.toString());
38-
writeFileSync(this.path + '/g1.dat', crs.getG1Data());
39-
writeFileSync(this.path + '/g2.dat', crs.getG2Data());
40+
writeFileSync(this.path + '/bn254_g1.dat', crs.getG1Data());
41+
writeFileSync(this.path + '/bn254_g2.dat', crs.getG2Data());
4042
}
4143

4244
/**
4345
* G1 points data for prover key.
4446
* @returns The points data.
4547
*/
4648
getG1Data(): Uint8Array {
47-
return readFileSync(this.path + '/g1.dat');
49+
return readFileSync(this.path + '/bn254_g1.dat');
4850
}
4951

5052
/**
5153
* G2 points data for verification key.
5254
* @returns The points data.
5355
*/
5456
getG2Data(): Uint8Array {
55-
return readFileSync(this.path + '/g2.dat');
57+
return readFileSync(this.path + '/bn254_g2.dat');
5658
}
5759
}
5860

0 commit comments

Comments
 (0)