mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-10 01:33:07 +00:00
Merge branch 'main' of github.com:mir-protocol/plonky2 into ripeMD
This commit is contained in:
commit
dc2d4b893b
10
README.md
10
README.md
@ -1,8 +1,6 @@
|
||||
# Plonky2
|
||||
# Plonky2 & more
|
||||
|
||||
Plonky2 is a SNARK implementation based on techniques from PLONK and FRI. It is the successor of [Plonky](https://github.com/mir-protocol/plonky), which was based on PLONK and Halo.
|
||||
|
||||
Plonky2 is built for speed, and features a highly efficient recursive circuit. On a Macbook Pro, recursive proofs can be generated in about 170 ms.
|
||||
This repository was originally for Plonky2, a SNARK implementation based on techniques from PLONK and FRI. It has since expanded to include tools such as Starky, a highly performant STARK implementation.
|
||||
|
||||
|
||||
## Documentation
|
||||
@ -44,9 +42,9 @@ static GLOBAL: Jemalloc = Jemalloc;
|
||||
Jemalloc is known to cause crashes when a binary compiled for x86 is run on an Apple silicon-based Mac under [Rosetta 2](https://support.apple.com/en-us/HT211861). If you are experiencing crashes on your Apple silicon Mac, run `rustc --print target-libdir`. The output should contain `aarch64-apple-darwin`. If the output contains `x86_64-apple-darwin`, then you are running the Rust toolchain for x86; we recommend switching to the native ARM version.
|
||||
|
||||
|
||||
## Copyright
|
||||
## Licenses
|
||||
|
||||
Plonky2 was developed by Polygon Zero (formerly Mir). While we plan to adopt an open source license, we haven't selected one yet, so all rights are reserved for the time being. Please reach out to us if you have thoughts on licensing.
|
||||
As this is a monorepo, see the individual crates within for license information.
|
||||
|
||||
|
||||
## Disclaimer
|
||||
|
||||
202
ecdsa/LICENSE-APACHE
Normal file
202
ecdsa/LICENSE-APACHE
Normal file
@ -0,0 +1,202 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
21
ecdsa/LICENSE-MIT
Normal file
21
ecdsa/LICENSE-MIT
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2022 The Plonky2 Authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
13
ecdsa/README.md
Normal file
13
ecdsa/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
## License
|
||||
|
||||
Licensed under either of
|
||||
|
||||
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
||||
|
||||
at your option.
|
||||
|
||||
|
||||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
|
||||
@ -25,6 +25,7 @@ keccak-rust = { git = "https://github.com/npwardberkeley/keccak-rust" }
|
||||
keccak-hash = "0.9.0"
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.3.5"
|
||||
hex = "0.4.3"
|
||||
|
||||
[features]
|
||||
@ -35,3 +36,7 @@ parallel = ["maybe_rayon/parallel"]
|
||||
[[bin]]
|
||||
name = "assemble"
|
||||
required-features = ["asmtools"]
|
||||
|
||||
[[bench]]
|
||||
name = "stack_manipulation"
|
||||
harness = false
|
||||
|
||||
75
evm/benches/stack_manipulation.rs
Normal file
75
evm/benches/stack_manipulation.rs
Normal file
@ -0,0 +1,75 @@
|
||||
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
|
||||
use plonky2_evm::cpu::kernel::assemble_to_bytes;
|
||||
|
||||
fn criterion_benchmark(c: &mut Criterion) {
|
||||
rotl_group(c);
|
||||
rotr_group(c);
|
||||
insert_group(c);
|
||||
delete_group(c);
|
||||
replace_group(c);
|
||||
shuffle_group(c);
|
||||
misc_group(c);
|
||||
}
|
||||
|
||||
fn rotl_group(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("rotl");
|
||||
group.sample_size(10);
|
||||
group.bench_function(BenchmarkId::from_parameter(8), |b| {
|
||||
b.iter(|| assemble("%stack (a, b, c, d, e, f, g, h) -> (b, c, d, e, f, g, h, a)"))
|
||||
});
|
||||
}
|
||||
|
||||
fn rotr_group(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("rotr");
|
||||
group.sample_size(10);
|
||||
group.bench_function(BenchmarkId::from_parameter(8), |b| {
|
||||
b.iter(|| assemble("%stack (a, b, c, d, e, f, g, h) -> (h, a, b, c, d, e, f, g)"))
|
||||
});
|
||||
}
|
||||
|
||||
fn insert_group(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("insert");
|
||||
group.sample_size(10);
|
||||
group.bench_function(BenchmarkId::from_parameter(8), |b| {
|
||||
b.iter(|| assemble("%stack (a, b, c, d, e, f, g, h) -> (a, b, c, d, 123, e, f, g, h)"))
|
||||
});
|
||||
}
|
||||
|
||||
fn delete_group(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("delete");
|
||||
group.sample_size(10);
|
||||
group.bench_function(BenchmarkId::from_parameter(8), |b| {
|
||||
b.iter(|| assemble("%stack (a, b, c, d, e, f, g, h) -> (a, b, c, e, f, g, h)"))
|
||||
});
|
||||
}
|
||||
|
||||
fn replace_group(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("replace");
|
||||
group.sample_size(10);
|
||||
group.bench_function(BenchmarkId::from_parameter(8), |b| {
|
||||
b.iter(|| assemble("%stack (a, b, c, d, e, f, g, h) -> (a, b, c, 5, e, f, g, h)"))
|
||||
});
|
||||
}
|
||||
|
||||
fn shuffle_group(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("shuffle");
|
||||
group.sample_size(10);
|
||||
group.bench_function(BenchmarkId::from_parameter(8), |b| {
|
||||
b.iter(|| assemble("%stack (a, b, c, d, e, f, g, h) -> (g, d, h, a, f, e, b, c)"))
|
||||
});
|
||||
}
|
||||
|
||||
fn misc_group(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("misc");
|
||||
group.sample_size(10);
|
||||
group.bench_function(BenchmarkId::from_parameter(8), |b| {
|
||||
b.iter(|| assemble("%stack (a, b, c, a, e, f, g, h) -> (g, 1, h, g, f, 3, b, b)"))
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(benches, criterion_benchmark);
|
||||
criterion_main!(benches);
|
||||
|
||||
fn assemble(code: &str) {
|
||||
assemble_to_bytes(&[code.into()]);
|
||||
}
|
||||
@ -260,6 +260,7 @@ mod tests {
|
||||
let mut row: cpu::columns::CpuColumnsView<F> =
|
||||
[F::ZERO; CpuStark::<F, D>::COLUMNS].into();
|
||||
row.is_cpu_cycle = F::ONE;
|
||||
row.is_kernel_mode = F::ONE;
|
||||
row.program_counter = F::from_canonical_usize(i);
|
||||
row.opcode = [
|
||||
(logic::columns::IS_AND, 0x16),
|
||||
@ -319,12 +320,263 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
// Trap to kernel
|
||||
{
|
||||
let mut row: cpu::columns::CpuColumnsView<F> =
|
||||
[F::ZERO; CpuStark::<F, D>::COLUMNS].into();
|
||||
let last_row: cpu::columns::CpuColumnsView<F> =
|
||||
cpu_trace_rows[cpu_trace_rows.len() - 1].into();
|
||||
row.is_cpu_cycle = F::ONE;
|
||||
row.opcode = F::from_canonical_u8(0x0a); // `EXP` is implemented in software
|
||||
row.is_kernel_mode = F::ONE;
|
||||
row.program_counter = last_row.program_counter + F::ONE;
|
||||
row.general.syscalls_mut().output = [
|
||||
row.program_counter,
|
||||
F::ONE,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
];
|
||||
cpu_stark.generate(row.borrow_mut());
|
||||
cpu_trace_rows.push(row.into());
|
||||
}
|
||||
|
||||
// `EXIT_KERNEL` (to kernel)
|
||||
{
|
||||
let mut row: cpu::columns::CpuColumnsView<F> =
|
||||
[F::ZERO; CpuStark::<F, D>::COLUMNS].into();
|
||||
row.is_cpu_cycle = F::ONE;
|
||||
row.opcode = F::from_canonical_u8(0xf9);
|
||||
row.is_kernel_mode = F::ONE;
|
||||
row.program_counter = F::from_canonical_usize(KERNEL.global_labels["sys_exp"]);
|
||||
row.general.jumps_mut().input0 = [
|
||||
F::from_canonical_u16(15682),
|
||||
F::ONE,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
];
|
||||
cpu_stark.generate(row.borrow_mut());
|
||||
cpu_trace_rows.push(row.into());
|
||||
}
|
||||
|
||||
// `JUMP` (in kernel mode)
|
||||
{
|
||||
let mut row: cpu::columns::CpuColumnsView<F> =
|
||||
[F::ZERO; CpuStark::<F, D>::COLUMNS].into();
|
||||
row.is_cpu_cycle = F::ONE;
|
||||
row.opcode = F::from_canonical_u8(0x56);
|
||||
row.is_kernel_mode = F::ONE;
|
||||
row.program_counter = F::from_canonical_u16(15682);
|
||||
row.general.jumps_mut().input0 = [
|
||||
F::from_canonical_u16(15106),
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
];
|
||||
row.general.jumps_mut().input1 = [
|
||||
F::ONE,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
];
|
||||
row.general.jumps_mut().input0_upper_zero = F::ONE;
|
||||
row.general.jumps_mut().dst_valid_or_kernel = F::ONE;
|
||||
row.general.jumps_mut().input0_jumpable = F::ONE;
|
||||
row.general.jumps_mut().input1_sum_inv = F::ONE;
|
||||
row.general.jumps_mut().should_jump = F::ONE;
|
||||
cpu_stark.generate(row.borrow_mut());
|
||||
cpu_trace_rows.push(row.into());
|
||||
}
|
||||
|
||||
// `EXIT_KERNEL` (to userspace)
|
||||
{
|
||||
let mut row: cpu::columns::CpuColumnsView<F> =
|
||||
[F::ZERO; CpuStark::<F, D>::COLUMNS].into();
|
||||
row.is_cpu_cycle = F::ONE;
|
||||
row.opcode = F::from_canonical_u8(0xf9);
|
||||
row.is_kernel_mode = F::ONE;
|
||||
row.program_counter = F::from_canonical_u16(15106);
|
||||
row.general.jumps_mut().input0 = [
|
||||
F::from_canonical_u16(63064),
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
];
|
||||
cpu_stark.generate(row.borrow_mut());
|
||||
cpu_trace_rows.push(row.into());
|
||||
}
|
||||
|
||||
// `JUMP` (taken)
|
||||
{
|
||||
let mut row: cpu::columns::CpuColumnsView<F> =
|
||||
[F::ZERO; CpuStark::<F, D>::COLUMNS].into();
|
||||
row.is_cpu_cycle = F::ONE;
|
||||
row.opcode = F::from_canonical_u8(0x56);
|
||||
row.is_kernel_mode = F::ZERO;
|
||||
row.program_counter = F::from_canonical_u16(63064);
|
||||
row.general.jumps_mut().input0 = [
|
||||
F::from_canonical_u16(3754),
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
];
|
||||
row.general.jumps_mut().input1 = [
|
||||
F::ONE,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
];
|
||||
row.general.jumps_mut().input0_upper_zero = F::ONE;
|
||||
row.general.jumps_mut().dst_valid = F::ONE;
|
||||
row.general.jumps_mut().dst_valid_or_kernel = F::ONE;
|
||||
row.general.jumps_mut().input0_jumpable = F::ONE;
|
||||
row.general.jumps_mut().input1_sum_inv = F::ONE;
|
||||
row.general.jumps_mut().should_jump = F::ONE;
|
||||
cpu_stark.generate(row.borrow_mut());
|
||||
cpu_trace_rows.push(row.into());
|
||||
}
|
||||
|
||||
// `JUMPI` (taken)
|
||||
{
|
||||
let mut row: cpu::columns::CpuColumnsView<F> =
|
||||
[F::ZERO; CpuStark::<F, D>::COLUMNS].into();
|
||||
row.is_cpu_cycle = F::ONE;
|
||||
row.opcode = F::from_canonical_u8(0x57);
|
||||
row.is_kernel_mode = F::ZERO;
|
||||
row.program_counter = F::from_canonical_u16(3754);
|
||||
row.general.jumps_mut().input0 = [
|
||||
F::from_canonical_u16(37543),
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
];
|
||||
row.general.jumps_mut().input1 = [
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ONE,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
];
|
||||
row.general.jumps_mut().input0_upper_zero = F::ONE;
|
||||
row.general.jumps_mut().dst_valid = F::ONE;
|
||||
row.general.jumps_mut().dst_valid_or_kernel = F::ONE;
|
||||
row.general.jumps_mut().input0_jumpable = F::ONE;
|
||||
row.general.jumps_mut().input1_sum_inv = F::ONE;
|
||||
row.general.jumps_mut().should_jump = F::ONE;
|
||||
cpu_stark.generate(row.borrow_mut());
|
||||
cpu_trace_rows.push(row.into());
|
||||
}
|
||||
|
||||
// `JUMPI` (not taken)
|
||||
{
|
||||
let mut row: cpu::columns::CpuColumnsView<F> =
|
||||
[F::ZERO; CpuStark::<F, D>::COLUMNS].into();
|
||||
row.is_cpu_cycle = F::ONE;
|
||||
row.opcode = F::from_canonical_u8(0x57);
|
||||
row.is_kernel_mode = F::ZERO;
|
||||
row.program_counter = F::from_canonical_u16(37543);
|
||||
row.general.jumps_mut().input0 = [
|
||||
F::from_canonical_u16(37543),
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ONE,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
];
|
||||
row.general.jumps_mut().input0_upper_sum_inv = F::ONE;
|
||||
row.general.jumps_mut().dst_valid = F::ONE;
|
||||
row.general.jumps_mut().dst_valid_or_kernel = F::ONE;
|
||||
row.general.jumps_mut().input0_jumpable = F::ZERO;
|
||||
row.general.jumps_mut().should_continue = F::ONE;
|
||||
cpu_stark.generate(row.borrow_mut());
|
||||
cpu_trace_rows.push(row.into());
|
||||
}
|
||||
|
||||
// `JUMP` (trapping)
|
||||
{
|
||||
let mut row: cpu::columns::CpuColumnsView<F> =
|
||||
[F::ZERO; CpuStark::<F, D>::COLUMNS].into();
|
||||
let last_row: cpu::columns::CpuColumnsView<F> =
|
||||
cpu_trace_rows[cpu_trace_rows.len() - 1].into();
|
||||
row.is_cpu_cycle = F::ONE;
|
||||
row.opcode = F::from_canonical_u8(0x56);
|
||||
row.is_kernel_mode = F::ZERO;
|
||||
row.program_counter = last_row.program_counter + F::ONE;
|
||||
row.general.jumps_mut().input0 = [
|
||||
F::from_canonical_u16(37543),
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ONE,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
];
|
||||
row.general.jumps_mut().input1 = [
|
||||
F::ONE,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
];
|
||||
row.general.jumps_mut().input0_upper_sum_inv = F::ONE;
|
||||
row.general.jumps_mut().dst_valid = F::ONE;
|
||||
row.general.jumps_mut().dst_valid_or_kernel = F::ONE;
|
||||
row.general.jumps_mut().input0_jumpable = F::ZERO;
|
||||
row.general.jumps_mut().input1_sum_inv = F::ONE;
|
||||
row.general.jumps_mut().should_trap = F::ONE;
|
||||
cpu_stark.generate(row.borrow_mut());
|
||||
cpu_trace_rows.push(row.into());
|
||||
}
|
||||
|
||||
// Pad to a power of two.
|
||||
for i in 0..cpu_trace_rows.len().next_power_of_two() - cpu_trace_rows.len() {
|
||||
let mut row: cpu::columns::CpuColumnsView<F> =
|
||||
[F::ZERO; CpuStark::<F, D>::COLUMNS].into();
|
||||
row.opcode = F::from_canonical_u8(0xff);
|
||||
row.is_cpu_cycle = F::ONE;
|
||||
row.program_counter = F::from_canonical_usize(i + num_logic_rows);
|
||||
row.is_kernel_mode = F::ONE;
|
||||
row.program_counter =
|
||||
F::from_canonical_usize(KERNEL.global_labels["fault_exception"] + i);
|
||||
cpu_stark.generate(row.borrow_mut());
|
||||
cpu_trace_rows.push(row.into());
|
||||
}
|
||||
|
||||
@ -8,6 +8,8 @@ pub(crate) union CpuGeneralColumnsView<T: Copy> {
|
||||
keccak: CpuKeccakView<T>,
|
||||
arithmetic: CpuArithmeticView<T>,
|
||||
logic: CpuLogicView<T>,
|
||||
jumps: CpuJumpsView<T>,
|
||||
syscalls: CpuSyscallsView<T>,
|
||||
}
|
||||
|
||||
impl<T: Copy> CpuGeneralColumnsView<T> {
|
||||
@ -40,6 +42,26 @@ impl<T: Copy> CpuGeneralColumnsView<T> {
|
||||
pub(crate) fn logic_mut(&mut self) -> &mut CpuLogicView<T> {
|
||||
unsafe { &mut self.logic }
|
||||
}
|
||||
|
||||
// SAFETY: Each view is a valid interpretation of the underlying array.
|
||||
pub(crate) fn jumps(&self) -> &CpuJumpsView<T> {
|
||||
unsafe { &self.jumps }
|
||||
}
|
||||
|
||||
// SAFETY: Each view is a valid interpretation of the underlying array.
|
||||
pub(crate) fn jumps_mut(&mut self) -> &mut CpuJumpsView<T> {
|
||||
unsafe { &mut self.jumps }
|
||||
}
|
||||
|
||||
// SAFETY: Each view is a valid interpretation of the underlying array.
|
||||
pub(crate) fn syscalls(&self) -> &CpuSyscallsView<T> {
|
||||
unsafe { &self.syscalls }
|
||||
}
|
||||
|
||||
// SAFETY: Each view is a valid interpretation of the underlying array.
|
||||
pub(crate) fn syscalls_mut(&mut self) -> &mut CpuSyscallsView<T> {
|
||||
unsafe { &mut self.syscalls }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + PartialEq> PartialEq<Self> for CpuGeneralColumnsView<T> {
|
||||
@ -91,5 +113,61 @@ pub(crate) struct CpuLogicView<T: Copy> {
|
||||
pub(crate) output: [T; 16],
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub(crate) struct CpuJumpsView<T: Copy> {
|
||||
/// Assuming a limb size of 32 bits.
|
||||
/// The top stack value at entry (for jumps, the address; for `EXIT_KERNEL`, the address and new
|
||||
/// privilege level).
|
||||
pub(crate) input0: [T; 8],
|
||||
/// For `JUMPI`, the second stack value (the predicate). For `JUMP`, 1.
|
||||
pub(crate) input1: [T; 8],
|
||||
|
||||
/// Inverse of `input0[1] + ... + input0[7]`, if one exists; otherwise, an arbitrary value.
|
||||
/// Needed to prove that `input0` is nonzero.
|
||||
pub(crate) input0_upper_sum_inv: T,
|
||||
/// 1 if `input0[1..7]` is zero; else 0.
|
||||
pub(crate) input0_upper_zero: T,
|
||||
|
||||
/// 1 if `input0[0]` is the address of a valid jump destination (i.e. `JUMPDEST` that is not
|
||||
/// part of a `PUSH` immediate); else 0. Note that the kernel is allowed to jump anywhere it
|
||||
/// wants, so this flag is computed but ignored in kernel mode.
|
||||
/// NOTE: this flag only considers `input0[0]`, the low 32 bits of the 256-bit register. Even if
|
||||
/// this flag is 1, `input0` will still be an invalid address if the high 224 bits are not 0.
|
||||
pub(crate) dst_valid: T, // TODO: populate this (check for JUMPDEST)
|
||||
/// 1 if either `dst_valid` is 1 or we are in kernel mode; else 0. (Just a logical OR.)
|
||||
pub(crate) dst_valid_or_kernel: T,
|
||||
/// 1 if `dst_valid_or_kernel` and `input0_upper_zero` are both 1; else 0. In other words, we
|
||||
/// are allowed to jump to `input0[0]` because either it's a valid address or we're in kernel
|
||||
/// mode (`dst_valid_or_kernel`), and also `input0[1..7]` are all 0 so `input0[0]` is in fact
|
||||
/// the whole address (we're not being asked to jump to an address that would overflow).
|
||||
pub(crate) input0_jumpable: T,
|
||||
|
||||
/// Inverse of `input1[0] + ... + input1[7]`, if one exists; otherwise, an arbitrary value.
|
||||
/// Needed to prove that `input1` is nonzero.
|
||||
pub(crate) input1_sum_inv: T,
|
||||
|
||||
/// Note that the below flags are mutually exclusive.
|
||||
/// 1 if the JUMPI falls though (because input1 is 0); else 0.
|
||||
pub(crate) should_continue: T,
|
||||
/// 1 if the JUMP/JUMPI does in fact jump to `input0`; else 0. This requires `input0` to be a
|
||||
/// valid destination (`input0[0]` is a `JUMPDEST` not in an immediate or we are in kernel mode
|
||||
/// and also `input0[1..7]` is 0) and `input1` to be nonzero.
|
||||
pub(crate) should_jump: T,
|
||||
/// 1 if the JUMP/JUMPI faults; else 0. This happens when `input0` is not a valid destination
|
||||
/// (`input0[0]` is not `JUMPDEST` that is not in an immediate while we are in user mode, or
|
||||
/// `input0[1..7]` is nonzero) and `input1` is nonzero.
|
||||
pub(crate) should_trap: T,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub(crate) struct CpuSyscallsView<T: Copy> {
|
||||
/// Assuming a limb size of 32 bits.
|
||||
/// The output contains the context that is required to from the system call in `EXIT_KERNEL`.
|
||||
/// `output[0]` contains the program counter at the time the system call was made (the address
|
||||
/// of the syscall instruction). `output[1]` is 1 if we were in kernel mode at the time and 0
|
||||
/// otherwise. `output[2]`, ..., `output[7]` are zero.
|
||||
pub(crate) output: [T; 8],
|
||||
}
|
||||
|
||||
// `u8` is guaranteed to have a `size_of` of 1.
|
||||
pub const NUM_SHARED_COLUMNS: usize = size_of::<CpuGeneralColumnsView<u8>>();
|
||||
|
||||
@ -17,9 +17,6 @@ pub struct CpuColumnsView<T: Copy> {
|
||||
/// Filter. 1 if the row is part of bootstrapping the kernel code, 0 otherwise.
|
||||
pub is_bootstrap_kernel: T,
|
||||
|
||||
/// Filter. 1 if the row is part of bootstrapping a contract's code, 0 otherwise.
|
||||
pub is_bootstrap_contract: T,
|
||||
|
||||
/// Filter. 1 if the row corresponds to a cycle of execution and 0 otherwise.
|
||||
/// Lets us re-use columns in non-cycle rows.
|
||||
pub is_cpu_cycle: T,
|
||||
@ -27,6 +24,9 @@ pub struct CpuColumnsView<T: Copy> {
|
||||
/// If CPU cycle: The program counter for the current instruction.
|
||||
pub program_counter: T,
|
||||
|
||||
/// If CPU cycle: We're in kernel (privileged) mode.
|
||||
pub is_kernel_mode: T,
|
||||
|
||||
/// If CPU cycle: The opcode being decoded, in {0, ..., 255}.
|
||||
pub opcode: T,
|
||||
|
||||
@ -92,8 +92,8 @@ pub struct CpuColumnsView<T: Copy> {
|
||||
pub is_mstore8: T,
|
||||
pub is_sload: T,
|
||||
pub is_sstore: T,
|
||||
pub is_jump: T,
|
||||
pub is_jumpi: T,
|
||||
pub is_jump: T, // Note: This column must be 0 when is_cpu_cycle = 0.
|
||||
pub is_jumpi: T, // Note: This column must be 0 when is_cpu_cycle = 0.
|
||||
pub is_pc: T,
|
||||
pub is_msize: T,
|
||||
pub is_gas: T,
|
||||
@ -142,8 +142,15 @@ pub struct CpuColumnsView<T: Copy> {
|
||||
pub is_invalid_11: T,
|
||||
pub is_invalid_12: T,
|
||||
pub is_invalid_13: T,
|
||||
pub is_invalid_14: T,
|
||||
pub is_invalid_15: T,
|
||||
pub is_invalid_16: T,
|
||||
pub is_invalid_17: T,
|
||||
pub is_invalid_18: T,
|
||||
pub is_invalid_19: T,
|
||||
pub is_invalid_20: T,
|
||||
|
||||
/// If CPU cycle: the opcode, broken up into bits in **big-endian** order.
|
||||
/// If CPU cycle: the opcode, broken up into bits in little-endian order.
|
||||
pub opcode_bits: [T; 8],
|
||||
|
||||
/// Filter. 1 iff a Keccak permutation is computed on this row.
|
||||
|
||||
@ -57,18 +57,24 @@ pub fn eval_packed_generic<P: PackedField>(
|
||||
|
||||
// If a row is a CPU cycle and executing a native instruction (implemented as a table row; not
|
||||
// microcoded) then the program counter is incremented by 1 to obtain the next row's program
|
||||
// counter.
|
||||
// counter. Also, the next row has the same kernel flag.
|
||||
let is_native_instruction: P = NATIVE_INSTRUCTIONS.iter().map(|&col_i| lv[col_i]).sum();
|
||||
yield_constr.constraint_transition(
|
||||
lv.is_cpu_cycle
|
||||
* is_native_instruction
|
||||
* (lv.program_counter - nv.program_counter + P::ONES),
|
||||
);
|
||||
yield_constr.constraint_transition(
|
||||
lv.is_cpu_cycle * is_native_instruction * (lv.is_kernel_mode - nv.is_kernel_mode),
|
||||
);
|
||||
|
||||
// If a non-CPU cycle row is followed by a CPU cycle row, then the `program_counter` of the CPU
|
||||
// cycle row is 0.
|
||||
// cycle row is 0 and it is in kernel mode.
|
||||
yield_constr
|
||||
.constraint_transition((lv.is_cpu_cycle - P::ONES) * nv.is_cpu_cycle * nv.program_counter);
|
||||
yield_constr.constraint_transition(
|
||||
(lv.is_cpu_cycle - P::ONES) * nv.is_cpu_cycle * (nv.is_kernel_mode - P::ONES),
|
||||
);
|
||||
|
||||
// The first row has nowhere to continue execution from, so if it's a cycle row, then its
|
||||
// `program_counter` must be 0.
|
||||
@ -84,6 +90,8 @@ pub fn eval_packed_generic<P: PackedField>(
|
||||
let (halt_pc0, halt_pc1) = get_halt_pcs::<P::Scalar>();
|
||||
yield_constr
|
||||
.constraint_last_row((lv.program_counter - halt_pc0) * (lv.program_counter - halt_pc1));
|
||||
// Finally, the last row must be in kernel mode.
|
||||
yield_constr.constraint_last_row(lv.is_kernel_mode - P::ONES);
|
||||
}
|
||||
|
||||
pub fn eval_ext_circuit<F: RichField + Extendable<D>, const D: usize>(
|
||||
@ -100,22 +108,27 @@ pub fn eval_ext_circuit<F: RichField + Extendable<D>, const D: usize>(
|
||||
|
||||
// If a row is a CPU cycle and executing a native instruction (implemented as a table row; not
|
||||
// microcoded) then the program counter is incremented by 1 to obtain the next row's program
|
||||
// counter.
|
||||
// counter. Also, the next row has the same kernel flag.
|
||||
{
|
||||
let is_native_instruction =
|
||||
builder.add_many_extension(NATIVE_INSTRUCTIONS.iter().map(|&col_i| lv[col_i]));
|
||||
let filter = builder.mul_extension(lv.is_cpu_cycle, is_native_instruction);
|
||||
let pc_diff = builder.sub_extension(lv.program_counter, nv.program_counter);
|
||||
let constr = builder.mul_add_extension(filter, pc_diff, filter);
|
||||
yield_constr.constraint_transition(builder, constr);
|
||||
let pc_constr = builder.mul_add_extension(filter, pc_diff, filter);
|
||||
yield_constr.constraint_transition(builder, pc_constr);
|
||||
let kernel_diff = builder.sub_extension(lv.is_kernel_mode, nv.is_kernel_mode);
|
||||
let kernel_constr = builder.mul_extension(filter, kernel_diff);
|
||||
yield_constr.constraint_transition(builder, kernel_constr);
|
||||
}
|
||||
|
||||
// If a non-CPU cycle row is followed by a CPU cycle row, then the `program_counter` of the CPU
|
||||
// cycle row is 0.
|
||||
// cycle row is 0 and it is in kernel mode.
|
||||
{
|
||||
let constr = builder.mul_extension(nv.is_cpu_cycle, nv.program_counter);
|
||||
let constr = builder.mul_sub_extension(lv.is_cpu_cycle, constr, constr);
|
||||
yield_constr.constraint_transition(builder, constr);
|
||||
let filter = builder.mul_sub_extension(lv.is_cpu_cycle, nv.is_cpu_cycle, nv.is_cpu_cycle);
|
||||
let pc_constr = builder.mul_extension(filter, nv.program_counter);
|
||||
yield_constr.constraint_transition(builder, pc_constr);
|
||||
let kernel_constr = builder.mul_sub_extension(filter, nv.is_kernel_mode, filter);
|
||||
yield_constr.constraint_transition(builder, kernel_constr);
|
||||
}
|
||||
|
||||
// The first row has nowhere to continue execution from, so if it's a cycle row, then its
|
||||
@ -147,4 +160,10 @@ pub fn eval_ext_circuit<F: RichField + Extendable<D>, const D: usize>(
|
||||
|
||||
yield_constr.constraint_last_row(builder, constr);
|
||||
}
|
||||
// Finally, the last row must be in kernel mode.
|
||||
{
|
||||
let one = builder.one_extension();
|
||||
let constr = builder.sub_extension(lv.is_kernel_mode, one);
|
||||
yield_constr.constraint_last_row(builder, constr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ use plonky2::hash::hash_types::RichField;
|
||||
|
||||
use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer};
|
||||
use crate::cpu::columns::{CpuColumnsView, COL_MAP, NUM_CPU_COLUMNS};
|
||||
use crate::cpu::{bootstrap_kernel, control_flow, decode, simple_logic};
|
||||
use crate::cpu::{bootstrap_kernel, control_flow, decode, jumps, simple_logic, syscalls};
|
||||
use crate::cross_table_lookup::Column;
|
||||
use crate::memory::NUM_CHANNELS;
|
||||
use crate::stark::Stark;
|
||||
@ -94,7 +94,9 @@ impl<F: RichField + Extendable<D>, const D: usize> Stark<F, D> for CpuStark<F, D
|
||||
bootstrap_kernel::eval_bootstrap_kernel(vars, yield_constr);
|
||||
control_flow::eval_packed_generic(local_values, next_values, yield_constr);
|
||||
decode::eval_packed_generic(local_values, yield_constr);
|
||||
jumps::eval_packed(local_values, next_values, yield_constr);
|
||||
simple_logic::eval_packed(local_values, yield_constr);
|
||||
syscalls::eval_packed(local_values, next_values, yield_constr);
|
||||
}
|
||||
|
||||
fn eval_ext_circuit(
|
||||
@ -108,7 +110,9 @@ impl<F: RichField + Extendable<D>, const D: usize> Stark<F, D> for CpuStark<F, D
|
||||
bootstrap_kernel::eval_bootstrap_kernel_circuit(builder, vars, yield_constr);
|
||||
control_flow::eval_ext_circuit(builder, local_values, next_values, yield_constr);
|
||||
decode::eval_ext_circuit(builder, local_values, yield_constr);
|
||||
jumps::eval_ext_circuit(builder, local_values, next_values, yield_constr);
|
||||
simple_logic::eval_ext_circuit(builder, local_values, yield_constr);
|
||||
syscalls::eval_ext_circuit(builder, local_values, next_values, yield_constr);
|
||||
}
|
||||
|
||||
fn constraint_degree(&self) -> usize {
|
||||
|
||||
@ -7,123 +7,144 @@ use plonky2::iop::ext_target::ExtensionTarget;
|
||||
use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer};
|
||||
use crate::cpu::columns::{CpuColumnsView, COL_MAP};
|
||||
|
||||
// List of opcode blocks
|
||||
// Each block corresponds to exactly one flag, and each flag corresponds to exactly one block.
|
||||
// Each block of opcodes:
|
||||
// - is contiguous
|
||||
// - has a length that is a power of 2
|
||||
// - its start index is a multiple of its length (it is aligned)
|
||||
// These properties permit us to check if an opcode belongs to a block of length 2^n by checking its
|
||||
// top 8-n bits.
|
||||
const OPCODES: [(u64, usize, usize); 106] = [
|
||||
// (start index of block, number of top bits to check (log2), flag column)
|
||||
(0x00, 0, COL_MAP.is_stop),
|
||||
(0x01, 0, COL_MAP.is_add),
|
||||
(0x02, 0, COL_MAP.is_mul),
|
||||
(0x03, 0, COL_MAP.is_sub),
|
||||
(0x04, 0, COL_MAP.is_div),
|
||||
(0x05, 0, COL_MAP.is_sdiv),
|
||||
(0x06, 0, COL_MAP.is_mod),
|
||||
(0x07, 0, COL_MAP.is_smod),
|
||||
(0x08, 0, COL_MAP.is_addmod),
|
||||
(0x09, 0, COL_MAP.is_mulmod),
|
||||
(0x0a, 0, COL_MAP.is_exp),
|
||||
(0x0b, 0, COL_MAP.is_signextend),
|
||||
(0x0c, 2, COL_MAP.is_invalid_0), // 0x0c-0x0f
|
||||
(0x10, 0, COL_MAP.is_lt),
|
||||
(0x11, 0, COL_MAP.is_gt),
|
||||
(0x12, 0, COL_MAP.is_slt),
|
||||
(0x13, 0, COL_MAP.is_sgt),
|
||||
(0x14, 0, COL_MAP.is_eq),
|
||||
(0x15, 0, COL_MAP.is_iszero),
|
||||
(0x16, 0, COL_MAP.is_and),
|
||||
(0x17, 0, COL_MAP.is_or),
|
||||
(0x18, 0, COL_MAP.is_xor),
|
||||
(0x19, 0, COL_MAP.is_not),
|
||||
(0x1a, 0, COL_MAP.is_byte),
|
||||
(0x1b, 0, COL_MAP.is_shl),
|
||||
(0x1c, 0, COL_MAP.is_shr),
|
||||
(0x1d, 0, COL_MAP.is_sar),
|
||||
(0x1e, 1, COL_MAP.is_invalid_1), // 0x1e-0x1f
|
||||
(0x20, 0, COL_MAP.is_keccak256),
|
||||
(0x21, 0, COL_MAP.is_invalid_2),
|
||||
(0x22, 1, COL_MAP.is_invalid_3), // 0x22-0x23
|
||||
(0x24, 2, COL_MAP.is_invalid_4), // 0x24-0x27
|
||||
(0x28, 3, COL_MAP.is_invalid_5), // 0x28-0x2f
|
||||
(0x30, 0, COL_MAP.is_address),
|
||||
(0x31, 0, COL_MAP.is_balance),
|
||||
(0x32, 0, COL_MAP.is_origin),
|
||||
(0x33, 0, COL_MAP.is_caller),
|
||||
(0x34, 0, COL_MAP.is_callvalue),
|
||||
(0x35, 0, COL_MAP.is_calldataload),
|
||||
(0x36, 0, COL_MAP.is_calldatasize),
|
||||
(0x37, 0, COL_MAP.is_calldatacopy),
|
||||
(0x38, 0, COL_MAP.is_codesize),
|
||||
(0x39, 0, COL_MAP.is_codecopy),
|
||||
(0x3a, 0, COL_MAP.is_gasprice),
|
||||
(0x3b, 0, COL_MAP.is_extcodesize),
|
||||
(0x3c, 0, COL_MAP.is_extcodecopy),
|
||||
(0x3d, 0, COL_MAP.is_returndatasize),
|
||||
(0x3e, 0, COL_MAP.is_returndatacopy),
|
||||
(0x3f, 0, COL_MAP.is_extcodehash),
|
||||
(0x40, 0, COL_MAP.is_blockhash),
|
||||
(0x41, 0, COL_MAP.is_coinbase),
|
||||
(0x42, 0, COL_MAP.is_timestamp),
|
||||
(0x43, 0, COL_MAP.is_number),
|
||||
(0x44, 0, COL_MAP.is_difficulty),
|
||||
(0x45, 0, COL_MAP.is_gaslimit),
|
||||
(0x46, 0, COL_MAP.is_chainid),
|
||||
(0x47, 0, COL_MAP.is_selfbalance),
|
||||
(0x48, 0, COL_MAP.is_basefee),
|
||||
(0x49, 0, COL_MAP.is_prover_input),
|
||||
(0x4a, 1, COL_MAP.is_invalid_6), // 0x4a-0x4b
|
||||
(0x4c, 2, COL_MAP.is_invalid_7), // 0x4c-0x4f
|
||||
(0x50, 0, COL_MAP.is_pop),
|
||||
(0x51, 0, COL_MAP.is_mload),
|
||||
(0x52, 0, COL_MAP.is_mstore),
|
||||
(0x53, 0, COL_MAP.is_mstore8),
|
||||
(0x54, 0, COL_MAP.is_sload),
|
||||
(0x55, 0, COL_MAP.is_sstore),
|
||||
(0x56, 0, COL_MAP.is_jump),
|
||||
(0x57, 0, COL_MAP.is_jumpi),
|
||||
(0x58, 0, COL_MAP.is_pc),
|
||||
(0x59, 0, COL_MAP.is_msize),
|
||||
(0x5a, 0, COL_MAP.is_gas),
|
||||
(0x5b, 0, COL_MAP.is_jumpdest),
|
||||
(0x5c, 0, COL_MAP.is_get_state_root),
|
||||
(0x5d, 0, COL_MAP.is_set_state_root),
|
||||
(0x5e, 0, COL_MAP.is_get_receipt_root),
|
||||
(0x5f, 0, COL_MAP.is_set_receipt_root),
|
||||
(0x60, 5, COL_MAP.is_push), // 0x60-0x7f
|
||||
(0x80, 4, COL_MAP.is_dup), // 0x80-0x8f
|
||||
(0x90, 4, COL_MAP.is_swap), // 0x90-0x9f
|
||||
(0xa0, 0, COL_MAP.is_log0),
|
||||
(0xa1, 0, COL_MAP.is_log1),
|
||||
(0xa2, 0, COL_MAP.is_log2),
|
||||
(0xa3, 0, COL_MAP.is_log3),
|
||||
(0xa4, 0, COL_MAP.is_log4),
|
||||
// Opcode 0xa5 is PANIC. Make the proof unverifiable by giving it no flag to decode to.
|
||||
(0xa6, 1, COL_MAP.is_invalid_8), // 0xa6-0xa7
|
||||
(0xa8, 3, COL_MAP.is_invalid_9), // 0xa8-0xaf
|
||||
(0xb0, 4, COL_MAP.is_invalid_10), // 0xb0-0xbf
|
||||
(0xc0, 5, COL_MAP.is_invalid_11), // 0xc0-0xdf
|
||||
(0xe0, 4, COL_MAP.is_invalid_12), // 0xe0-0xef
|
||||
(0xf0, 0, COL_MAP.is_create),
|
||||
(0xf1, 0, COL_MAP.is_call),
|
||||
(0xf2, 0, COL_MAP.is_callcode),
|
||||
(0xf3, 0, COL_MAP.is_return),
|
||||
(0xf4, 0, COL_MAP.is_delegatecall),
|
||||
(0xf5, 0, COL_MAP.is_create2),
|
||||
(0xf6, 0, COL_MAP.is_get_context),
|
||||
(0xf7, 0, COL_MAP.is_set_context),
|
||||
(0xf8, 0, COL_MAP.is_consume_gas),
|
||||
(0xf9, 0, COL_MAP.is_exit_kernel),
|
||||
(0xfa, 0, COL_MAP.is_staticcall),
|
||||
(0xfb, 0, COL_MAP.is_mload_general),
|
||||
(0xfc, 0, COL_MAP.is_mstore_general),
|
||||
(0xfd, 0, COL_MAP.is_revert),
|
||||
(0xfe, 0, COL_MAP.is_invalid_13),
|
||||
(0xff, 0, COL_MAP.is_selfdestruct),
|
||||
#[derive(PartialEq, Eq)]
|
||||
enum Availability {
|
||||
All,
|
||||
User,
|
||||
Kernel,
|
||||
}
|
||||
use Availability::{All, Kernel, User};
|
||||
|
||||
/// List of opcode blocks
|
||||
/// Each block corresponds to exactly one flag, and each flag corresponds to exactly one block.
|
||||
/// Each block of opcodes:
|
||||
/// - is contiguous,
|
||||
/// - has a length that is a power of 2, and
|
||||
/// - its start index is a multiple of its length (it is aligned).
|
||||
/// These properties permit us to check if an opcode belongs to a block of length 2^n by checking
|
||||
/// its top 8-n bits.
|
||||
/// Additionally, each block can be made available only to the user, only to the kernel, or to
|
||||
/// both. This is mainly useful for making some instructions kernel-only, while still decoding to
|
||||
/// invalid for the user. We do this by making one kernel-only block and another user-only block.
|
||||
/// The exception is the PANIC instruction which is user-only without a corresponding kernel block.
|
||||
/// This makes the proof unverifiable when PANIC is executed in kernel mode, which is the intended
|
||||
/// behavior.
|
||||
const OPCODES: [(u8, usize, Availability, usize); 113] = [
|
||||
// (start index of block, number of top bits to check (log2), availability, flag column)
|
||||
(0x00, 0, All, COL_MAP.is_stop),
|
||||
(0x01, 0, All, COL_MAP.is_add),
|
||||
(0x02, 0, All, COL_MAP.is_mul),
|
||||
(0x03, 0, All, COL_MAP.is_sub),
|
||||
(0x04, 0, All, COL_MAP.is_div),
|
||||
(0x05, 0, All, COL_MAP.is_sdiv),
|
||||
(0x06, 0, All, COL_MAP.is_mod),
|
||||
(0x07, 0, All, COL_MAP.is_smod),
|
||||
(0x08, 0, All, COL_MAP.is_addmod),
|
||||
(0x09, 0, All, COL_MAP.is_mulmod),
|
||||
(0x0a, 0, All, COL_MAP.is_exp),
|
||||
(0x0b, 0, All, COL_MAP.is_signextend),
|
||||
(0x0c, 2, All, COL_MAP.is_invalid_0), // 0x0c-0x0f
|
||||
(0x10, 0, All, COL_MAP.is_lt),
|
||||
(0x11, 0, All, COL_MAP.is_gt),
|
||||
(0x12, 0, All, COL_MAP.is_slt),
|
||||
(0x13, 0, All, COL_MAP.is_sgt),
|
||||
(0x14, 0, All, COL_MAP.is_eq),
|
||||
(0x15, 0, All, COL_MAP.is_iszero),
|
||||
(0x16, 0, All, COL_MAP.is_and),
|
||||
(0x17, 0, All, COL_MAP.is_or),
|
||||
(0x18, 0, All, COL_MAP.is_xor),
|
||||
(0x19, 0, All, COL_MAP.is_not),
|
||||
(0x1a, 0, All, COL_MAP.is_byte),
|
||||
(0x1b, 0, All, COL_MAP.is_shl),
|
||||
(0x1c, 0, All, COL_MAP.is_shr),
|
||||
(0x1d, 0, All, COL_MAP.is_sar),
|
||||
(0x1e, 1, All, COL_MAP.is_invalid_1), // 0x1e-0x1f
|
||||
(0x20, 0, All, COL_MAP.is_keccak256),
|
||||
(0x21, 0, All, COL_MAP.is_invalid_2),
|
||||
(0x22, 1, All, COL_MAP.is_invalid_3), // 0x22-0x23
|
||||
(0x24, 2, All, COL_MAP.is_invalid_4), // 0x24-0x27
|
||||
(0x28, 3, All, COL_MAP.is_invalid_5), // 0x28-0x2f
|
||||
(0x30, 0, All, COL_MAP.is_address),
|
||||
(0x31, 0, All, COL_MAP.is_balance),
|
||||
(0x32, 0, All, COL_MAP.is_origin),
|
||||
(0x33, 0, All, COL_MAP.is_caller),
|
||||
(0x34, 0, All, COL_MAP.is_callvalue),
|
||||
(0x35, 0, All, COL_MAP.is_calldataload),
|
||||
(0x36, 0, All, COL_MAP.is_calldatasize),
|
||||
(0x37, 0, All, COL_MAP.is_calldatacopy),
|
||||
(0x38, 0, All, COL_MAP.is_codesize),
|
||||
(0x39, 0, All, COL_MAP.is_codecopy),
|
||||
(0x3a, 0, All, COL_MAP.is_gasprice),
|
||||
(0x3b, 0, All, COL_MAP.is_extcodesize),
|
||||
(0x3c, 0, All, COL_MAP.is_extcodecopy),
|
||||
(0x3d, 0, All, COL_MAP.is_returndatasize),
|
||||
(0x3e, 0, All, COL_MAP.is_returndatacopy),
|
||||
(0x3f, 0, All, COL_MAP.is_extcodehash),
|
||||
(0x40, 0, All, COL_MAP.is_blockhash),
|
||||
(0x41, 0, All, COL_MAP.is_coinbase),
|
||||
(0x42, 0, All, COL_MAP.is_timestamp),
|
||||
(0x43, 0, All, COL_MAP.is_number),
|
||||
(0x44, 0, All, COL_MAP.is_difficulty),
|
||||
(0x45, 0, All, COL_MAP.is_gaslimit),
|
||||
(0x46, 0, All, COL_MAP.is_chainid),
|
||||
(0x47, 0, All, COL_MAP.is_selfbalance),
|
||||
(0x48, 0, All, COL_MAP.is_basefee),
|
||||
(0x49, 0, User, COL_MAP.is_invalid_6),
|
||||
(0x49, 0, Kernel, COL_MAP.is_prover_input),
|
||||
(0x4a, 1, All, COL_MAP.is_invalid_7), // 0x4a-0x4b
|
||||
(0x4c, 2, All, COL_MAP.is_invalid_8), // 0x4c-0x4f
|
||||
(0x50, 0, All, COL_MAP.is_pop),
|
||||
(0x51, 0, All, COL_MAP.is_mload),
|
||||
(0x52, 0, All, COL_MAP.is_mstore),
|
||||
(0x53, 0, All, COL_MAP.is_mstore8),
|
||||
(0x54, 0, All, COL_MAP.is_sload),
|
||||
(0x55, 0, All, COL_MAP.is_sstore),
|
||||
(0x56, 0, All, COL_MAP.is_jump),
|
||||
(0x57, 0, All, COL_MAP.is_jumpi),
|
||||
(0x58, 0, All, COL_MAP.is_pc),
|
||||
(0x59, 0, All, COL_MAP.is_msize),
|
||||
(0x5a, 0, All, COL_MAP.is_gas),
|
||||
(0x5b, 0, All, COL_MAP.is_jumpdest),
|
||||
(0x5c, 2, User, COL_MAP.is_invalid_9), // 0x5c-5f
|
||||
(0x5c, 0, Kernel, COL_MAP.is_get_state_root),
|
||||
(0x5d, 0, Kernel, COL_MAP.is_set_state_root),
|
||||
(0x5e, 0, Kernel, COL_MAP.is_get_receipt_root),
|
||||
(0x5f, 0, Kernel, COL_MAP.is_set_receipt_root),
|
||||
(0x60, 5, All, COL_MAP.is_push), // 0x60-0x7f
|
||||
(0x80, 4, All, COL_MAP.is_dup), // 0x80-0x8f
|
||||
(0x90, 4, All, COL_MAP.is_swap), // 0x90-0x9f
|
||||
(0xa0, 0, All, COL_MAP.is_log0),
|
||||
(0xa1, 0, All, COL_MAP.is_log1),
|
||||
(0xa2, 0, All, COL_MAP.is_log2),
|
||||
(0xa3, 0, All, COL_MAP.is_log3),
|
||||
(0xa4, 0, All, COL_MAP.is_log4),
|
||||
(0xa5, 0, User, COL_MAP.is_invalid_10),
|
||||
// Opcode 0xa5 is PANIC when Kernel. Make the proof unverifiable by giving it no flag to decode to.
|
||||
(0xa6, 1, All, COL_MAP.is_invalid_11), // 0xa6-0xa7
|
||||
(0xa8, 3, All, COL_MAP.is_invalid_12), // 0xa8-0xaf
|
||||
(0xb0, 4, All, COL_MAP.is_invalid_13), // 0xb0-0xbf
|
||||
(0xc0, 5, All, COL_MAP.is_invalid_14), // 0xc0-0xdf
|
||||
(0xe0, 4, All, COL_MAP.is_invalid_15), // 0xe0-0xef
|
||||
(0xf0, 0, All, COL_MAP.is_create),
|
||||
(0xf1, 0, All, COL_MAP.is_call),
|
||||
(0xf2, 0, All, COL_MAP.is_callcode),
|
||||
(0xf3, 0, All, COL_MAP.is_return),
|
||||
(0xf4, 0, All, COL_MAP.is_delegatecall),
|
||||
(0xf5, 0, All, COL_MAP.is_create2),
|
||||
(0xf6, 1, User, COL_MAP.is_invalid_16), // 0xf6-0xf7
|
||||
(0xf6, 0, Kernel, COL_MAP.is_get_context),
|
||||
(0xf7, 0, Kernel, COL_MAP.is_set_context),
|
||||
(0xf8, 1, User, COL_MAP.is_invalid_17), // 0xf8-0xf9
|
||||
(0xf8, 0, Kernel, COL_MAP.is_consume_gas),
|
||||
(0xf9, 0, Kernel, COL_MAP.is_exit_kernel),
|
||||
(0xfa, 0, All, COL_MAP.is_staticcall),
|
||||
(0xfb, 0, User, COL_MAP.is_invalid_18),
|
||||
(0xfb, 0, Kernel, COL_MAP.is_mload_general),
|
||||
(0xfc, 0, User, COL_MAP.is_invalid_19),
|
||||
(0xfc, 0, Kernel, COL_MAP.is_mstore_general),
|
||||
(0xfd, 0, All, COL_MAP.is_revert),
|
||||
(0xfe, 0, All, COL_MAP.is_invalid_20),
|
||||
(0xff, 0, All, COL_MAP.is_selfdestruct),
|
||||
];
|
||||
|
||||
pub fn generate<F: RichField>(lv: &mut CpuColumnsView<F>) {
|
||||
@ -139,12 +160,13 @@ pub fn generate<F: RichField>(lv: &mut CpuColumnsView<F>) {
|
||||
|
||||
let opcode = lv.opcode.to_canonical_u64();
|
||||
assert!(opcode < 256, "opcode should be in {{0, ..., 255}}");
|
||||
let opcode = opcode as u8;
|
||||
|
||||
for (i, bit) in lv.opcode_bits.iter_mut().enumerate() {
|
||||
*bit = F::from_canonical_u64((opcode >> (7 - i)) & 1);
|
||||
*bit = F::from_bool(opcode & (1 << i) != 0);
|
||||
}
|
||||
|
||||
let top_bits: [u64; 9] = [
|
||||
let top_bits: [u8; 9] = [
|
||||
0,
|
||||
opcode & 0x80,
|
||||
opcode & 0xc0,
|
||||
@ -156,54 +178,101 @@ pub fn generate<F: RichField>(lv: &mut CpuColumnsView<F>) {
|
||||
opcode,
|
||||
];
|
||||
|
||||
for (oc, block_length, col) in OPCODES {
|
||||
lv[col] = F::from_bool(top_bits[8 - block_length] == oc);
|
||||
let kernel = lv.is_kernel_mode.to_canonical_u64();
|
||||
assert!(kernel <= 1);
|
||||
let kernel = kernel != 0;
|
||||
|
||||
for (oc, block_length, availability, col) in OPCODES {
|
||||
let available = match availability {
|
||||
All => true,
|
||||
User => !kernel,
|
||||
Kernel => kernel,
|
||||
};
|
||||
let opcode_match = top_bits[8 - block_length] == oc;
|
||||
lv[col] = F::from_bool(available && opcode_match);
|
||||
}
|
||||
}
|
||||
|
||||
/// Break up an opcode (which is 8 bits long) into its eight bits.
|
||||
const fn bits_from_opcode(opcode: u8) -> [bool; 8] {
|
||||
[
|
||||
opcode & (1 << 0) != 0,
|
||||
opcode & (1 << 1) != 0,
|
||||
opcode & (1 << 2) != 0,
|
||||
opcode & (1 << 3) != 0,
|
||||
opcode & (1 << 4) != 0,
|
||||
opcode & (1 << 5) != 0,
|
||||
opcode & (1 << 6) != 0,
|
||||
opcode & (1 << 7) != 0,
|
||||
]
|
||||
}
|
||||
|
||||
pub fn eval_packed_generic<P: PackedField>(
|
||||
lv: &CpuColumnsView<P>,
|
||||
yield_constr: &mut ConstraintConsumer<P>,
|
||||
) {
|
||||
let cycle_filter = lv.is_cpu_cycle;
|
||||
|
||||
// Ensure that the kernel flag is valid (either 0 or 1).
|
||||
let kernel_mode = lv.is_kernel_mode;
|
||||
yield_constr.constraint(cycle_filter * kernel_mode * (kernel_mode - P::ONES));
|
||||
|
||||
// Ensure that the opcode bits are valid: each has to be either 0 or 1, and they must match
|
||||
// the opcode. Note that this also validates that this implicitly range-checks the opcode.
|
||||
// the opcode. Note that this also implicitly range-checks the opcode.
|
||||
let bits = lv.opcode_bits;
|
||||
// First check that the bits are either 0 or 1.
|
||||
for bit in bits {
|
||||
yield_constr.constraint(cycle_filter * bit * (bit - P::ONES));
|
||||
}
|
||||
|
||||
// top_bits[i] is the opcode with all but the top i bits cleared.
|
||||
let top_bits = {
|
||||
let mut top_bits = [P::ZEROS; 9];
|
||||
for i in 0..8 {
|
||||
top_bits[i + 1] = top_bits[i] + bits[i] * P::Scalar::from_canonical_u64(1 << (7 - i));
|
||||
}
|
||||
top_bits
|
||||
};
|
||||
|
||||
// Now check that they match the opcode.
|
||||
let opcode = lv.opcode;
|
||||
yield_constr.constraint(cycle_filter * (opcode - top_bits[8]));
|
||||
{
|
||||
let opcode = lv.opcode;
|
||||
let reconstructed_opcode: P = bits
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(i, bit)| bit * P::Scalar::from_canonical_u64(1 << i))
|
||||
.sum();
|
||||
yield_constr.constraint(cycle_filter * (opcode - reconstructed_opcode));
|
||||
}
|
||||
|
||||
// Check that the instruction flags are valid.
|
||||
// First, check that they are all either 0 or 1.
|
||||
for (_, _, flag_col) in OPCODES {
|
||||
for (_, _, _, flag_col) in OPCODES {
|
||||
let flag = lv[flag_col];
|
||||
yield_constr.constraint(cycle_filter * flag * (flag - P::ONES));
|
||||
}
|
||||
// Now check that exactly one is 1.
|
||||
let flag_sum: P = OPCODES
|
||||
.into_iter()
|
||||
.map(|(_, _, flag_col)| lv[flag_col])
|
||||
.map(|(_, _, _, flag_col)| lv[flag_col])
|
||||
.sum();
|
||||
yield_constr.constraint(cycle_filter * (P::ONES - flag_sum));
|
||||
|
||||
// Finally, classify all opcodes into blocks
|
||||
for (oc, block_length, col) in OPCODES {
|
||||
let constr = lv[col] * (top_bits[8 - block_length] - P::Scalar::from_canonical_u64(oc));
|
||||
// Finally, classify all opcodes, together with the kernel flag, into blocks
|
||||
for (oc, block_length, availability, col) in OPCODES {
|
||||
// 0 if the block/flag is available to us (is always available, is user-only and we are in
|
||||
// user mode, or kernel-only and we are in kernel mode) and 1 otherwise.
|
||||
let unavailable = match availability {
|
||||
All => P::ZEROS,
|
||||
User => kernel_mode,
|
||||
Kernel => P::ONES - kernel_mode,
|
||||
};
|
||||
// 0 if all the opcode bits match, and something in {1, ..., 8}, otherwise.
|
||||
let opcode_mismatch: P = bits
|
||||
.into_iter()
|
||||
.zip(bits_from_opcode(oc))
|
||||
.rev()
|
||||
.take(block_length + 1)
|
||||
.map(|(row_bit, flag_bit)| match flag_bit {
|
||||
// 1 if the bit does not match, and 0 otherwise
|
||||
false => row_bit,
|
||||
true => P::ONES - row_bit,
|
||||
})
|
||||
.sum();
|
||||
|
||||
// If unavailable + opcode_mismatch is 0, then the opcode bits all match and we are in the
|
||||
// correct mode.
|
||||
let constr = lv[col] * (unavailable + opcode_mismatch);
|
||||
yield_constr.constraint(cycle_filter * constr);
|
||||
}
|
||||
}
|
||||
@ -213,10 +282,20 @@ pub fn eval_ext_circuit<F: RichField + Extendable<D>, const D: usize>(
|
||||
lv: &CpuColumnsView<ExtensionTarget<D>>,
|
||||
yield_constr: &mut RecursiveConstraintConsumer<F, D>,
|
||||
) {
|
||||
let one = builder.one_extension();
|
||||
|
||||
let cycle_filter = lv.is_cpu_cycle;
|
||||
|
||||
// Ensure that the kernel flag is valid (either 0 or 1).
|
||||
let kernel_mode = lv.is_kernel_mode;
|
||||
{
|
||||
let constr = builder.mul_sub_extension(kernel_mode, kernel_mode, kernel_mode);
|
||||
let constr = builder.mul_extension(cycle_filter, constr);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
|
||||
// Ensure that the opcode bits are valid: each has to be either 0 or 1, and they must match
|
||||
// the opcode. Note that this also validates that this implicitly range-checks the opcode.
|
||||
// the opcode. Note that this also implicitly range-checks the opcode.
|
||||
let bits = lv.opcode_bits;
|
||||
// First check that the bits are either 0 or 1.
|
||||
for bit in bits {
|
||||
@ -224,38 +303,32 @@ pub fn eval_ext_circuit<F: RichField + Extendable<D>, const D: usize>(
|
||||
let constr = builder.mul_extension(cycle_filter, constr);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
|
||||
let top_bits = {
|
||||
let mut top_bits = [builder.zero_extension(); 9];
|
||||
for i in 0..8 {
|
||||
top_bits[i + 1] = builder.mul_const_add_extension(
|
||||
F::from_canonical_u64(1 << (7 - i)),
|
||||
bits[i],
|
||||
top_bits[i],
|
||||
);
|
||||
}
|
||||
top_bits
|
||||
};
|
||||
|
||||
// Now check that the bits match the opcode.
|
||||
// Now check that they match the opcode.
|
||||
{
|
||||
let constr = builder.sub_extension(lv.opcode, top_bits[8]);
|
||||
let constr = builder.mul_extension(cycle_filter, constr);
|
||||
let opcode = lv.opcode;
|
||||
let reconstructed_opcode =
|
||||
bits.into_iter()
|
||||
.enumerate()
|
||||
.fold(builder.zero_extension(), |cumul, (i, bit)| {
|
||||
builder.mul_const_add_extension(F::from_canonical_u64(1 << i), bit, cumul)
|
||||
});
|
||||
let diff = builder.sub_extension(opcode, reconstructed_opcode);
|
||||
let constr = builder.mul_extension(cycle_filter, diff);
|
||||
yield_constr.constraint(builder, constr);
|
||||
};
|
||||
}
|
||||
|
||||
// Check that the instruction flags are valid.
|
||||
// First, check that they are all either 0 or 1.
|
||||
for (_, _, flag_col) in OPCODES {
|
||||
for (_, _, _, flag_col) in OPCODES {
|
||||
let flag = lv[flag_col];
|
||||
let constr = builder.mul_sub_extension(flag, flag, flag);
|
||||
let constr = builder.mul_extension(cycle_filter, constr);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
// Now check that they sum to 1.
|
||||
// Now check that exactly one is 1.
|
||||
{
|
||||
let mut constr = builder.one_extension();
|
||||
for (_, _, flag_col) in OPCODES {
|
||||
for (_, _, _, flag_col) in OPCODES {
|
||||
let flag = lv[flag_col];
|
||||
constr = builder.sub_extension(constr, flag);
|
||||
}
|
||||
@ -263,11 +336,33 @@ pub fn eval_ext_circuit<F: RichField + Extendable<D>, const D: usize>(
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
|
||||
for (oc, block_length, col) in OPCODES {
|
||||
let flag = lv[col];
|
||||
let constr = builder.constant_extension(F::from_canonical_u64(oc).into());
|
||||
let constr = builder.sub_extension(top_bits[8 - block_length], constr);
|
||||
let constr = builder.mul_extension(flag, constr);
|
||||
// Finally, classify all opcodes, together with the kernel flag, into blocks
|
||||
for (oc, block_length, availability, col) in OPCODES {
|
||||
// 0 if the block/flag is available to us (is always available, is user-only and we are in
|
||||
// user mode, or kernel-only and we are in kernel mode) and 1 otherwise.
|
||||
let unavailable = match availability {
|
||||
All => builder.zero_extension(),
|
||||
User => kernel_mode,
|
||||
Kernel => builder.sub_extension(one, kernel_mode),
|
||||
};
|
||||
// 0 if all the opcode bits match, and something in {1, ..., 8}, otherwise.
|
||||
let opcode_mismatch = bits
|
||||
.into_iter()
|
||||
.zip(bits_from_opcode(oc))
|
||||
.rev()
|
||||
.take(block_length + 1)
|
||||
.fold(builder.zero_extension(), |cumul, (row_bit, flag_bit)| {
|
||||
let to_add = match flag_bit {
|
||||
false => row_bit,
|
||||
true => builder.sub_extension(one, row_bit),
|
||||
};
|
||||
builder.add_extension(cumul, to_add)
|
||||
});
|
||||
|
||||
// If unavailable + opcode_mismatch is 0, then the opcode bits all match and we are in the
|
||||
// correct mode.
|
||||
let constr = builder.add_extension(unavailable, opcode_mismatch);
|
||||
let constr = builder.mul_extension(lv[col], constr);
|
||||
let constr = builder.mul_extension(cycle_filter, constr);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
|
||||
353
evm/src/cpu/jumps.rs
Normal file
353
evm/src/cpu/jumps.rs
Normal file
@ -0,0 +1,353 @@
|
||||
use once_cell::sync::Lazy;
|
||||
use plonky2::field::extension::Extendable;
|
||||
use plonky2::field::packed::PackedField;
|
||||
use plonky2::field::types::Field;
|
||||
use plonky2::hash::hash_types::RichField;
|
||||
use plonky2::iop::ext_target::ExtensionTarget;
|
||||
|
||||
use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer};
|
||||
use crate::cpu::columns::CpuColumnsView;
|
||||
use crate::cpu::kernel::aggregator::KERNEL;
|
||||
|
||||
static INVALID_DST_HANDLER_ADDR: Lazy<usize> =
|
||||
Lazy::new(|| KERNEL.global_labels["fault_exception"]);
|
||||
|
||||
pub fn eval_packed_exit_kernel<P: PackedField>(
|
||||
lv: &CpuColumnsView<P>,
|
||||
nv: &CpuColumnsView<P>,
|
||||
yield_constr: &mut ConstraintConsumer<P>,
|
||||
) {
|
||||
let jumps_lv = lv.general.jumps();
|
||||
|
||||
// If we are executing `EXIT_KERNEL` then we simply restore the program counter and kernel mode
|
||||
// flag. The top 6 (32-bit) limbs are ignored (this is not part of the spec, but we trust the
|
||||
// kernel to set them to zero).
|
||||
yield_constr.constraint_transition(
|
||||
lv.is_cpu_cycle * lv.is_exit_kernel * (jumps_lv.input0[0] - nv.program_counter),
|
||||
);
|
||||
yield_constr.constraint_transition(
|
||||
lv.is_cpu_cycle * lv.is_exit_kernel * (jumps_lv.input0[1] - nv.is_kernel_mode),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn eval_ext_circuit_exit_kernel<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut plonky2::plonk::circuit_builder::CircuitBuilder<F, D>,
|
||||
lv: &CpuColumnsView<ExtensionTarget<D>>,
|
||||
nv: &CpuColumnsView<ExtensionTarget<D>>,
|
||||
yield_constr: &mut RecursiveConstraintConsumer<F, D>,
|
||||
) {
|
||||
let jumps_lv = lv.general.jumps();
|
||||
let filter = builder.mul_extension(lv.is_cpu_cycle, lv.is_exit_kernel);
|
||||
|
||||
// If we are executing `EXIT_KERNEL` then we simply restore the program counter and kernel mode
|
||||
// flag. The top 6 (32-bit) limbs are ignored (this is not part of the spec, but we trust the
|
||||
// kernel to set them to zero).
|
||||
|
||||
let pc_constr = builder.sub_extension(jumps_lv.input0[0], nv.program_counter);
|
||||
let pc_constr = builder.mul_extension(filter, pc_constr);
|
||||
yield_constr.constraint_transition(builder, pc_constr);
|
||||
|
||||
let kernel_constr = builder.sub_extension(jumps_lv.input0[1], nv.is_kernel_mode);
|
||||
let kernel_constr = builder.mul_extension(filter, kernel_constr);
|
||||
yield_constr.constraint_transition(builder, kernel_constr);
|
||||
}
|
||||
|
||||
pub fn eval_packed_jump_jumpi<P: PackedField>(
|
||||
lv: &CpuColumnsView<P>,
|
||||
nv: &CpuColumnsView<P>,
|
||||
yield_constr: &mut ConstraintConsumer<P>,
|
||||
) {
|
||||
let jumps_lv = lv.general.jumps();
|
||||
let filter = lv.is_jump + lv.is_jumpi; // `JUMP` or `JUMPI`
|
||||
|
||||
// If `JUMP`, re-use the `JUMPI` logic, but setting the second input (the predicate) to be 1.
|
||||
// In other words, we implement `JUMP(addr)` as `JUMPI(addr, cond=1)`.
|
||||
yield_constr.constraint(lv.is_jump * (jumps_lv.input1[0] - P::ONES));
|
||||
for &limb in &jumps_lv.input1[1..] {
|
||||
// Set all limbs (other than the least-significant limb) to 0.
|
||||
// NB: Technically, they don't have to be 0, as long as the sum
|
||||
// `input1[0] + ... + input1[7]` cannot overflow.
|
||||
yield_constr.constraint(lv.is_jump * limb);
|
||||
}
|
||||
|
||||
// Check `input0_upper_zero`
|
||||
// `input0_upper_zero` is either 0 or 1.
|
||||
yield_constr
|
||||
.constraint(filter * jumps_lv.input0_upper_zero * (jumps_lv.input0_upper_zero - P::ONES));
|
||||
// The below sum cannot overflow due to the limb size.
|
||||
let input0_upper_sum: P = jumps_lv.input0[1..].iter().copied().sum();
|
||||
// `input0_upper_zero` = 1 implies `input0_upper_sum` = 0.
|
||||
yield_constr.constraint(filter * jumps_lv.input0_upper_zero * input0_upper_sum);
|
||||
// `input0_upper_zero` = 0 implies `input0_upper_sum_inv * input0_upper_sum` = 1, which can only
|
||||
// happen when `input0_upper_sum` is nonzero.
|
||||
yield_constr.constraint(
|
||||
filter
|
||||
* (jumps_lv.input0_upper_sum_inv * input0_upper_sum + jumps_lv.input0_upper_zero
|
||||
- P::ONES),
|
||||
);
|
||||
|
||||
// Check `dst_valid_or_kernel` (this is just a logical OR)
|
||||
yield_constr.constraint(
|
||||
filter
|
||||
* (jumps_lv.dst_valid + lv.is_kernel_mode
|
||||
- jumps_lv.dst_valid * lv.is_kernel_mode
|
||||
- jumps_lv.dst_valid_or_kernel),
|
||||
);
|
||||
|
||||
// Check `input0_jumpable` (this is just `dst_valid_or_kernel` AND `input0_upper_zero`)
|
||||
yield_constr.constraint(
|
||||
filter
|
||||
* (jumps_lv.dst_valid_or_kernel * jumps_lv.input0_upper_zero
|
||||
- jumps_lv.input0_jumpable),
|
||||
);
|
||||
|
||||
// Make sure that `should_continue`, `should_jump`, `should_trap` are all binary and exactly one
|
||||
// is set.
|
||||
yield_constr
|
||||
.constraint(filter * jumps_lv.should_continue * (jumps_lv.should_continue - P::ONES));
|
||||
yield_constr.constraint(filter * jumps_lv.should_jump * (jumps_lv.should_jump - P::ONES));
|
||||
yield_constr.constraint(filter * jumps_lv.should_trap * (jumps_lv.should_trap - P::ONES));
|
||||
yield_constr.constraint(
|
||||
filter * (jumps_lv.should_continue + jumps_lv.should_jump + jumps_lv.should_trap - P::ONES),
|
||||
);
|
||||
|
||||
// Validate `should_continue`
|
||||
// This sum cannot overflow (due to limb size).
|
||||
let input1_sum: P = jumps_lv.input1.into_iter().sum();
|
||||
// `should_continue` = 1 implies `input1_sum` = 0.
|
||||
yield_constr.constraint(filter * jumps_lv.should_continue * input1_sum);
|
||||
// `should_continue` = 0 implies `input1_sum * input1_sum_inv` = 1, which can only happen if
|
||||
// input1_sum is nonzero.
|
||||
yield_constr.constraint(
|
||||
filter * (input1_sum * jumps_lv.input1_sum_inv + jumps_lv.should_continue - P::ONES),
|
||||
);
|
||||
|
||||
// Validate `should_jump` and `should_trap` by splitting on `input0_jumpable`.
|
||||
// Note that `should_jump` = 1 and `should_trap` = 1 both imply that `should_continue` = 0, so
|
||||
// `input1` is nonzero.
|
||||
yield_constr.constraint(filter * jumps_lv.should_jump * (jumps_lv.input0_jumpable - P::ONES));
|
||||
yield_constr.constraint(filter * jumps_lv.should_trap * jumps_lv.input0_jumpable);
|
||||
|
||||
// Handle trap
|
||||
// Set program counter and kernel flag
|
||||
yield_constr
|
||||
.constraint_transition(filter * jumps_lv.should_trap * (nv.is_kernel_mode - P::ONES));
|
||||
yield_constr.constraint_transition(
|
||||
filter
|
||||
* jumps_lv.should_trap
|
||||
* (nv.program_counter - P::Scalar::from_canonical_usize(*INVALID_DST_HANDLER_ADDR)),
|
||||
);
|
||||
|
||||
// Handle continue and jump
|
||||
let continue_or_jump = jumps_lv.should_continue + jumps_lv.should_jump;
|
||||
// Keep kernel mode.
|
||||
yield_constr
|
||||
.constraint_transition(filter * continue_or_jump * (nv.is_kernel_mode - lv.is_kernel_mode));
|
||||
// Set program counter depending on whether we're continuing or jumping.
|
||||
yield_constr.constraint_transition(
|
||||
filter * jumps_lv.should_continue * (nv.program_counter - lv.program_counter - P::ONES),
|
||||
);
|
||||
yield_constr.constraint_transition(
|
||||
filter * jumps_lv.should_jump * (nv.program_counter - jumps_lv.input0[0]),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn eval_ext_circuit_jump_jumpi<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut plonky2::plonk::circuit_builder::CircuitBuilder<F, D>,
|
||||
lv: &CpuColumnsView<ExtensionTarget<D>>,
|
||||
nv: &CpuColumnsView<ExtensionTarget<D>>,
|
||||
yield_constr: &mut RecursiveConstraintConsumer<F, D>,
|
||||
) {
|
||||
let jumps_lv = lv.general.jumps();
|
||||
let filter = builder.add_extension(lv.is_jump, lv.is_jumpi); // `JUMP` or `JUMPI`
|
||||
|
||||
// If `JUMP`, re-use the `JUMPI` logic, but setting the second input (the predicate) to be 1.
|
||||
// In other words, we implement `JUMP(addr)` as `JUMPI(addr, cond=1)`.
|
||||
{
|
||||
let constr = builder.mul_sub_extension(lv.is_jump, jumps_lv.input1[0], lv.is_jump);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
for &limb in &jumps_lv.input1[1..] {
|
||||
// Set all limbs (other than the least-significant limb) to 0.
|
||||
// NB: Technically, they don't have to be 0, as long as the sum
|
||||
// `input1[0] + ... + input1[7]` cannot overflow.
|
||||
let constr = builder.mul_extension(lv.is_jump, limb);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
|
||||
// Check `input0_upper_zero`
|
||||
// `input0_upper_zero` is either 0 or 1.
|
||||
{
|
||||
let constr = builder.mul_sub_extension(
|
||||
jumps_lv.input0_upper_zero,
|
||||
jumps_lv.input0_upper_zero,
|
||||
jumps_lv.input0_upper_zero,
|
||||
);
|
||||
let constr = builder.mul_extension(filter, constr);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
{
|
||||
// The below sum cannot overflow due to the limb size.
|
||||
let input0_upper_sum = builder.add_many_extension(jumps_lv.input0[1..].iter());
|
||||
|
||||
// `input0_upper_zero` = 1 implies `input0_upper_sum` = 0.
|
||||
let constr = builder.mul_extension(jumps_lv.input0_upper_zero, input0_upper_sum);
|
||||
let constr = builder.mul_extension(filter, constr);
|
||||
yield_constr.constraint(builder, constr);
|
||||
|
||||
// `input0_upper_zero` = 0 implies `input0_upper_sum_inv * input0_upper_sum` = 1, which can
|
||||
// only happen when `input0_upper_sum` is nonzero.
|
||||
let constr = builder.mul_add_extension(
|
||||
jumps_lv.input0_upper_sum_inv,
|
||||
input0_upper_sum,
|
||||
jumps_lv.input0_upper_zero,
|
||||
);
|
||||
let constr = builder.mul_sub_extension(filter, constr, filter);
|
||||
yield_constr.constraint(builder, constr);
|
||||
};
|
||||
|
||||
// Check `dst_valid_or_kernel` (this is just a logical OR)
|
||||
{
|
||||
let constr = builder.mul_add_extension(
|
||||
jumps_lv.dst_valid,
|
||||
lv.is_kernel_mode,
|
||||
jumps_lv.dst_valid_or_kernel,
|
||||
);
|
||||
let constr = builder.sub_extension(jumps_lv.dst_valid, constr);
|
||||
let constr = builder.add_extension(lv.is_kernel_mode, constr);
|
||||
let constr = builder.mul_extension(filter, constr);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
|
||||
// Check `input0_jumpable` (this is just `dst_valid_or_kernel` AND `input0_upper_zero`)
|
||||
{
|
||||
let constr = builder.mul_sub_extension(
|
||||
jumps_lv.dst_valid_or_kernel,
|
||||
jumps_lv.input0_upper_zero,
|
||||
jumps_lv.input0_jumpable,
|
||||
);
|
||||
let constr = builder.mul_extension(filter, constr);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
|
||||
// Make sure that `should_continue`, `should_jump`, `should_trap` are all binary and exactly one
|
||||
// is set.
|
||||
for flag in [
|
||||
jumps_lv.should_continue,
|
||||
jumps_lv.should_jump,
|
||||
jumps_lv.should_trap,
|
||||
] {
|
||||
let constr = builder.mul_sub_extension(flag, flag, flag);
|
||||
let constr = builder.mul_extension(filter, constr);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
{
|
||||
let constr = builder.add_extension(jumps_lv.should_continue, jumps_lv.should_jump);
|
||||
let constr = builder.add_extension(constr, jumps_lv.should_trap);
|
||||
let constr = builder.mul_sub_extension(filter, constr, filter);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
|
||||
// Validate `should_continue`
|
||||
{
|
||||
// This sum cannot overflow (due to limb size).
|
||||
let input1_sum = builder.add_many_extension(jumps_lv.input1.into_iter());
|
||||
|
||||
// `should_continue` = 1 implies `input1_sum` = 0.
|
||||
let constr = builder.mul_extension(jumps_lv.should_continue, input1_sum);
|
||||
let constr = builder.mul_extension(filter, constr);
|
||||
yield_constr.constraint(builder, constr);
|
||||
|
||||
// `should_continue` = 0 implies `input1_sum * input1_sum_inv` = 1, which can only happen if
|
||||
// input1_sum is nonzero.
|
||||
let constr = builder.mul_add_extension(
|
||||
input1_sum,
|
||||
jumps_lv.input1_sum_inv,
|
||||
jumps_lv.should_continue,
|
||||
);
|
||||
let constr = builder.mul_sub_extension(filter, constr, filter);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
|
||||
// Validate `should_jump` and `should_trap` by splitting on `input0_jumpable`.
|
||||
// Note that `should_jump` = 1 and `should_trap` = 1 both imply that `should_continue` = 0, so
|
||||
// `input1` is nonzero.
|
||||
{
|
||||
let constr = builder.mul_sub_extension(
|
||||
jumps_lv.should_jump,
|
||||
jumps_lv.input0_jumpable,
|
||||
jumps_lv.should_jump,
|
||||
);
|
||||
let constr = builder.mul_extension(filter, constr);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
{
|
||||
let constr = builder.mul_extension(jumps_lv.should_trap, jumps_lv.input0_jumpable);
|
||||
let constr = builder.mul_extension(filter, constr);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
|
||||
// Handle trap
|
||||
{
|
||||
let trap_filter = builder.mul_extension(filter, jumps_lv.should_trap);
|
||||
|
||||
// Set kernel flag
|
||||
let constr = builder.mul_sub_extension(trap_filter, nv.is_kernel_mode, trap_filter);
|
||||
yield_constr.constraint_transition(builder, constr);
|
||||
|
||||
// Set program counter
|
||||
let constr = builder.arithmetic_extension(
|
||||
F::ONE,
|
||||
-F::from_canonical_usize(*INVALID_DST_HANDLER_ADDR),
|
||||
trap_filter,
|
||||
nv.program_counter,
|
||||
trap_filter,
|
||||
);
|
||||
yield_constr.constraint_transition(builder, constr);
|
||||
}
|
||||
|
||||
// Handle continue and jump
|
||||
{
|
||||
// Keep kernel mode.
|
||||
let continue_or_jump =
|
||||
builder.add_extension(jumps_lv.should_continue, jumps_lv.should_jump);
|
||||
let constr = builder.sub_extension(nv.is_kernel_mode, lv.is_kernel_mode);
|
||||
let constr = builder.mul_extension(continue_or_jump, constr);
|
||||
let constr = builder.mul_extension(filter, constr);
|
||||
yield_constr.constraint_transition(builder, constr);
|
||||
}
|
||||
// Set program counter depending on whether we're continuing...
|
||||
{
|
||||
let constr = builder.sub_extension(nv.program_counter, lv.program_counter);
|
||||
let constr =
|
||||
builder.mul_sub_extension(jumps_lv.should_continue, constr, jumps_lv.should_continue);
|
||||
let constr = builder.mul_extension(filter, constr);
|
||||
yield_constr.constraint_transition(builder, constr);
|
||||
}
|
||||
// ...or jumping.
|
||||
{
|
||||
let constr = builder.sub_extension(nv.program_counter, jumps_lv.input0[0]);
|
||||
let constr = builder.mul_extension(jumps_lv.should_jump, constr);
|
||||
let constr = builder.mul_extension(filter, constr);
|
||||
yield_constr.constraint_transition(builder, constr);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eval_packed<P: PackedField>(
|
||||
lv: &CpuColumnsView<P>,
|
||||
nv: &CpuColumnsView<P>,
|
||||
yield_constr: &mut ConstraintConsumer<P>,
|
||||
) {
|
||||
eval_packed_exit_kernel(lv, nv, yield_constr);
|
||||
eval_packed_jump_jumpi(lv, nv, yield_constr);
|
||||
}
|
||||
|
||||
pub fn eval_ext_circuit<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut plonky2::plonk::circuit_builder::CircuitBuilder<F, D>,
|
||||
lv: &CpuColumnsView<ExtensionTarget<D>>,
|
||||
nv: &CpuColumnsView<ExtensionTarget<D>>,
|
||||
yield_constr: &mut RecursiveConstraintConsumer<F, D>,
|
||||
) {
|
||||
eval_ext_circuit_exit_kernel(builder, lv, nv, yield_constr);
|
||||
eval_ext_circuit_jump_jumpi(builder, lv, nv, yield_constr);
|
||||
}
|
||||
@ -11,6 +11,15 @@ pub static KERNEL: Lazy<Kernel> = Lazy::new(combined_kernel);
|
||||
|
||||
pub(crate) fn combined_kernel() -> Kernel {
|
||||
let files = vec![
|
||||
include_str!("asm/core/bootloader.asm"),
|
||||
include_str!("asm/core/create.asm"),
|
||||
include_str!("asm/core/create_addresses.asm"),
|
||||
include_str!("asm/core/intrinsic_gas.asm"),
|
||||
include_str!("asm/core/nonce.asm"),
|
||||
include_str!("asm/core/process_txn.asm"),
|
||||
include_str!("asm/core/terminate.asm"),
|
||||
include_str!("asm/core/transfer.asm"),
|
||||
include_str!("asm/core/util.asm"),
|
||||
include_str!("asm/curve/bn254/curve_add.asm"),
|
||||
include_str!("asm/curve/bn254/curve_mul.asm"),
|
||||
include_str!("asm/curve/bn254/moddiv.asm"),
|
||||
@ -25,13 +34,14 @@ pub(crate) fn combined_kernel() -> Kernel {
|
||||
include_str!("asm/halt.asm"),
|
||||
include_str!("asm/memory/core.asm"),
|
||||
include_str!("asm/memory/memcpy.asm"),
|
||||
include_str!("asm/memory/metadata.asm"),
|
||||
include_str!("asm/memory/packing.asm"),
|
||||
include_str!("asm/memory/txn_fields.asm"),
|
||||
include_str!("asm/rlp/encode.asm"),
|
||||
include_str!("asm/rlp/decode.asm"),
|
||||
include_str!("asm/rlp/read_to_memory.asm"),
|
||||
include_str!("asm/storage/read.asm"),
|
||||
include_str!("asm/storage/write.asm"),
|
||||
include_str!("asm/transactions/process_normalized.asm"),
|
||||
include_str!("asm/transactions/router.asm"),
|
||||
include_str!("asm/transactions/type_0.asm"),
|
||||
include_str!("asm/transactions/type_1.asm"),
|
||||
|
||||
11
evm/src/cpu/kernel/asm/core/bootloader.asm
Normal file
11
evm/src/cpu/kernel/asm/core/bootloader.asm
Normal file
@ -0,0 +1,11 @@
|
||||
// Loads some prover-provided contract code into the code segment of memory,
|
||||
// then hashes the code and returns the hash.
|
||||
|
||||
global bootload_contract:
|
||||
// stack: retdest
|
||||
|
||||
// TODO
|
||||
|
||||
// stack: code_hash, retdest
|
||||
SWAP1
|
||||
JUMP
|
||||
59
evm/src/cpu/kernel/asm/core/call.asm
Normal file
59
evm/src/cpu/kernel/asm/core/call.asm
Normal file
@ -0,0 +1,59 @@
|
||||
// Handlers for call-like operations, namely CALL, CALLCODE, STATICCALL and DELEGATECALL.
|
||||
|
||||
// Creates a new sub context and executes the code of the given account.
|
||||
global call:
|
||||
// stack: gas, address, value, args_offset, args_size, ret_offset, ret_size
|
||||
%address
|
||||
%stack (self, gas, address, value)
|
||||
// These are (should_transfer_value, value, static, gas, sender, storage, code_addr)
|
||||
-> (1, value, 0, gas, self, address, address)
|
||||
%jump(call_common)
|
||||
|
||||
// Creates a new sub context as if calling itself, but with the code of the
|
||||
// given account. In particular the storage remains the same.
|
||||
global call_code:
|
||||
// stack: gas, address, value, args_offset, args_size, ret_offset, ret_size
|
||||
%address
|
||||
%stack (self, gas, address, value)
|
||||
// These are (should_transfer_value, value, static, gas, sender, storage, code_addr)
|
||||
-> (1, value, 0, gas, self, self, address)
|
||||
%jump(call_common)
|
||||
|
||||
// Creates a new sub context and executes the code of the given account.
|
||||
// Equivalent to CALL, except that it does not allow any state modifying
|
||||
// instructions or sending ETH in the sub context. The disallowed instructions
|
||||
// are CREATE, CREATE2, LOG0, LOG1, LOG2, LOG3, LOG4, SSTORE, SELFDESTRUCT and
|
||||
// CALL if the value sent is not 0.
|
||||
global static_all:
|
||||
// stack: gas, address, args_offset, args_size, ret_offset, ret_size
|
||||
%address
|
||||
%stack (self, gas, address)
|
||||
// These are (should_transfer_value, value, static, gas, sender, storage, code_addr)
|
||||
-> (0, 0, 1, gas, self, address, address)
|
||||
%jump(call_common)
|
||||
|
||||
// Creates a new sub context as if calling itself, but with the code of the
|
||||
// given account. In particular the storage, the current sender and the current
|
||||
// value remain the same.
|
||||
global delegate_call:
|
||||
// stack: gas, address, args_offset, args_size, ret_offset, ret_size
|
||||
%address
|
||||
%sender
|
||||
%callvalue
|
||||
%stack (self, sender, value, gas, address)
|
||||
// These are (should_transfer_value, value, static, gas, sender, storage, code_addr)
|
||||
-> (0, value, 0, gas, sender, self, address)
|
||||
%jump(call_common)
|
||||
|
||||
call_common:
|
||||
// stack: should_transfer_value, value, static, gas, sender, storage, code_addr, args_offset, args_size, ret_offset, ret_size
|
||||
// TODO: Set all the appropriate metadata fields...
|
||||
%create_context
|
||||
// stack: new_ctx, after_call
|
||||
// Now, switch to the new context and go to usermode with PC=0.
|
||||
SET_CONTEXT
|
||||
PUSH 0
|
||||
EXIT_KERNEL
|
||||
|
||||
after_call:
|
||||
// TODO: Set RETURNDATA etc.
|
||||
84
evm/src/cpu/kernel/asm/core/create.asm
Normal file
84
evm/src/cpu/kernel/asm/core/create.asm
Normal file
@ -0,0 +1,84 @@
|
||||
// Create a new contract account with the traditional address scheme, i.e.
|
||||
// address = KEC(RLP(sender, nonce))[12:]
|
||||
// This can be used both for the CREATE instruction and for contract-creation
|
||||
// transactions.
|
||||
//
|
||||
// Pre stack: CODE_ADDR, code_len, retdest
|
||||
// Post stack: address
|
||||
// Note: CODE_ADDR refers to a (context, segment, offset) tuple.
|
||||
global create:
|
||||
// stack: sender, endowment, CODE_ADDR, code_len, retdest
|
||||
DUP1 %get_nonce
|
||||
// stack: nonce, sender, endowment, CODE_ADDR, code_len, retdest
|
||||
// Call get_create_address and have it return to create_inner.
|
||||
%stack (nonce, sender)
|
||||
-> (sender, nonce, create_inner, sender)
|
||||
%jump(get_create_address)
|
||||
|
||||
// CREATE2; see EIP-1014. Address will be
|
||||
// address = KEC(0xff || sender || salt || code_hash)[12:]
|
||||
//
|
||||
// Pre stack: sender, endowment, salt, CODE_ADDR, code_len, retdest
|
||||
// Post stack: address
|
||||
// Note: CODE_ADDR refers to a (context, segment, offset) tuple.
|
||||
global create2:
|
||||
// stack: sender, endowment, salt, CODE_ADDR, code_len, retdest
|
||||
// Call get_create2_address and have it return to create_inner.
|
||||
%stack (sender, endowment, salt) -> (salt, sender, endowment)
|
||||
// stack: salt, sender, endowment, CODE_ADDR, code_len, retdest
|
||||
DUP7 DUP7 DUP7 DUP7 // CODE_ADDR and code_len
|
||||
// stack: CODE_ADDR, code_len, salt, sender, endowment, CODE_ADDR, code_len, retdest
|
||||
PUSH create_inner
|
||||
// stack: create_inner, CODE_ADDR, code_len, salt, sender, endowment, CODE_ADDR, code_len, retdest
|
||||
SWAP5 // create_inner <-> salt
|
||||
// stack: salt, CODE_ADDR, code_len, create_inner, sender, endowment, CODE_ADDR, code_len, retdest
|
||||
DUP7 // sender
|
||||
// stack: sender, salt, CODE_ADDR, code_len, create_inner, sender, endowment, CODE_ADDR, code_len, retdest
|
||||
%jump(get_create2_address)
|
||||
|
||||
// Pre stack: address, sender, endowment, CODE_ADDR, code_len, retdest
|
||||
// Post stack: address
|
||||
// Note: CODE_ADDR refers to a (context, segment, offset) tuple.
|
||||
create_inner:
|
||||
// stack: address, sender, endowment, CODE_ADDR, code_len, retdest
|
||||
%stack (address, sender, endowment)
|
||||
-> (sender, address, endowment, sender, address)
|
||||
// TODO: Need to handle insufficient balance failure.
|
||||
%transfer_eth
|
||||
// stack: sender, address, CODE_ADDR, code_len, retdest
|
||||
|
||||
%increment_nonce
|
||||
// stack: address, CODE_ADDR, code_len, retdest
|
||||
|
||||
%create_context
|
||||
// stack: new_ctx, address, CODE_ADDR, code_len, retdest
|
||||
%stack (new_ctx, address, src_ctx, src_segment, src_offset, code_len)
|
||||
-> (new_ctx, @SEGMENT_CODE, 0,
|
||||
src_ctx, src_segment, src_offset,
|
||||
code_len, run_constructor,
|
||||
new_ctx, address)
|
||||
%jump(memcpy)
|
||||
|
||||
run_constructor:
|
||||
// stack: new_ctx, address, retdest
|
||||
// At this point, the initialization code has been loaded.
|
||||
// Save our return address in memory, so we'll be in `after_constructor`
|
||||
// after the new context returns.
|
||||
// Note: We can't use %mstore_context_metadata because we're writing to
|
||||
// memory owned by the new context, not the current one.
|
||||
%stack (new_ctx) -> (new_ctx, @SEGMENT_CONTEXT_METADATA,
|
||||
@CTX_METADATA_PARENT_PC, after_constructor, new_ctx)
|
||||
MSTORE_GENERAL
|
||||
// stack: new_ctx, address, retdest
|
||||
|
||||
// Now, switch to the new context and go to usermode with PC=0.
|
||||
SET_CONTEXT
|
||||
// stack: (empty, since we're in the new context)
|
||||
PUSH 0
|
||||
EXIT_KERNEL
|
||||
|
||||
after_constructor:
|
||||
// stack: address, retdest
|
||||
// TODO: If code was returned, store it in the account.
|
||||
SWAP1
|
||||
JUMP
|
||||
27
evm/src/cpu/kernel/asm/core/create_addresses.asm
Normal file
27
evm/src/cpu/kernel/asm/core/create_addresses.asm
Normal file
@ -0,0 +1,27 @@
|
||||
// Computes the address of a contract based on the conventional scheme, i.e.
|
||||
// address = KEC(RLP(sender, nonce))[12:]
|
||||
//
|
||||
// Pre stack: sender, nonce, retdest
|
||||
// Post stack: address
|
||||
global get_create_address:
|
||||
// stack: sender, nonce, retdest
|
||||
// TODO: Replace with actual implementation.
|
||||
%pop2
|
||||
PUSH 123
|
||||
SWAP1
|
||||
JUMP
|
||||
|
||||
// Computes the address for a contract based on the CREATE2 rule, i.e.
|
||||
// address = KEC(0xff || sender || salt || code_hash)[12:]
|
||||
//
|
||||
// Pre stack: sender, salt, CODE_ADDR, code_len, retdest
|
||||
// Post stack: address
|
||||
//
|
||||
// Note: CODE_ADDR is a (context, segment, offset) tuple.
|
||||
global get_create2_address:
|
||||
// stack: sender, salt, CODE_ADDR, code_len, retdest
|
||||
// TODO: Replace with actual implementation.
|
||||
%pop6
|
||||
PUSH 123
|
||||
SWAP1
|
||||
JUMP
|
||||
65
evm/src/cpu/kernel/asm/core/intrinsic_gas.asm
Normal file
65
evm/src/cpu/kernel/asm/core/intrinsic_gas.asm
Normal file
@ -0,0 +1,65 @@
|
||||
// After the transaction data has been parsed into a normalized set of fields
|
||||
// (see NormalizedTxnField), this routine processes the transaction.
|
||||
|
||||
global intrinsic_gas:
|
||||
// stack: retdest
|
||||
// Calculate the number of zero and nonzero bytes in the txn data.
|
||||
PUSH 0 // zeros = 0
|
||||
PUSH 0 // i = 0
|
||||
|
||||
count_zeros_loop:
|
||||
// stack: i, zeros, retdest
|
||||
DUP1
|
||||
%mload_txn_field(@TXN_FIELD_DATA_LEN)
|
||||
EQ
|
||||
// stack: i == data.len, i, zeros, retdest
|
||||
%jumpi(count_zeros_finish)
|
||||
|
||||
// stack: i, zeros, retdest
|
||||
DUP1
|
||||
%mload_kernel(@SEGMENT_TXN_DATA)
|
||||
ISZERO
|
||||
// stack: data[i] == 0, i, zeros
|
||||
%stack (data_i_is_zero, i, zeros) -> (data_i_is_zero, zeros, i)
|
||||
ADD
|
||||
// stack: zeros', i, retdest
|
||||
SWAP1
|
||||
// stack: i, zeros', retdest
|
||||
%add_const(1)
|
||||
// stack: i', zeros', retdest
|
||||
%jump(count_zeros_loop)
|
||||
|
||||
count_zeros_finish:
|
||||
// stack: i, zeros, retdest
|
||||
POP
|
||||
// stack: zeros, retdest
|
||||
DUP1
|
||||
// stack: zeros, zeros, retdest
|
||||
%mload_txn_field(@TXN_FIELD_DATA_LEN)
|
||||
// stack: data.len, zeros, zeros, retdest
|
||||
SUB
|
||||
// stack: nonzeros, zeros, retdest
|
||||
%mul_const(@GAS_TXDATANONZERO)
|
||||
// stack: gas_nonzeros, zeros, retdest
|
||||
SWAP1
|
||||
%mul_const(@GAS_TXDATAZERO)
|
||||
// stack: gas_zeros, gas_nonzeros, retdest
|
||||
ADD
|
||||
// stack: gas_txndata, retdest
|
||||
|
||||
%is_contract_creation
|
||||
%mul_const(@GAS_TXCREATE)
|
||||
// stack: gas_creation, gas_txndata, retdest
|
||||
|
||||
PUSH @GAS_TRANSACTION
|
||||
// stack: gas_txn, gas_creation, gas_txndata, retdest
|
||||
|
||||
// TODO: Add num_access_list_addresses * GAS_ACCESSLISTADDRESS
|
||||
// TODO: Add num_access_list_slots * GAS_ACCESSLISTSTORAGE
|
||||
|
||||
ADD
|
||||
ADD
|
||||
// stack: total_gas, retdest
|
||||
|
||||
SWAP1
|
||||
JUMP
|
||||
28
evm/src/cpu/kernel/asm/core/nonce.asm
Normal file
28
evm/src/cpu/kernel/asm/core/nonce.asm
Normal file
@ -0,0 +1,28 @@
|
||||
// Increment the nonce of the given account.
|
||||
// Pre stack: address, retdest
|
||||
// Post stack: (empty)
|
||||
|
||||
global get_nonce:
|
||||
// stack: address, retdest
|
||||
// TODO: Replace with actual implementation.
|
||||
JUMP
|
||||
|
||||
// Convenience macro to call get_nonce and return where we left off.
|
||||
%macro get_nonce
|
||||
%stack (address) -> (address, %%after)
|
||||
%jump(get_nonce)
|
||||
%%after:
|
||||
%endmacro
|
||||
|
||||
global increment_nonce:
|
||||
// stack: address, retdest
|
||||
// TODO: Replace with actual implementation.
|
||||
POP
|
||||
JUMP
|
||||
|
||||
// Convenience macro to call increment_nonce and return where we left off.
|
||||
%macro increment_nonce
|
||||
%stack (address) -> (address, %%after)
|
||||
%jump(increment_nonce)
|
||||
%%after:
|
||||
%endmacro
|
||||
39
evm/src/cpu/kernel/asm/core/process_txn.asm
Normal file
39
evm/src/cpu/kernel/asm/core/process_txn.asm
Normal file
@ -0,0 +1,39 @@
|
||||
// After the transaction data has been parsed into a normalized set of fields
|
||||
// (see NormalizedTxnField), this routine processes the transaction.
|
||||
|
||||
global process_normalized_txn:
|
||||
// stack: (empty)
|
||||
PUSH validate
|
||||
%jump(intrinsic_gas)
|
||||
|
||||
validate:
|
||||
// stack: intrinsic_gas
|
||||
// TODO: Check gas >= intrinsic_gas.
|
||||
// TODO: Check sender_balance >= intrinsic_gas + value.
|
||||
|
||||
buy_gas:
|
||||
// TODO: Deduct gas from sender (some may be refunded later).
|
||||
|
||||
increment_nonce:
|
||||
// TODO: Increment nonce.
|
||||
|
||||
process_based_on_type:
|
||||
%is_contract_creation
|
||||
%jumpi(process_contract_creation_txn)
|
||||
%jump(process_message_txn)
|
||||
|
||||
process_contract_creation_txn:
|
||||
// stack: (empty)
|
||||
// Push the code address & length onto the stack, then call `create`.
|
||||
%mload_txn_field(@TXN_FIELD_DATA_LEN)
|
||||
// stack: code_len
|
||||
PUSH 0
|
||||
// stack: code_offset, code_len
|
||||
PUSH @SEGMENT_TXN_DATA
|
||||
// stack: code_segment, code_offset, code_len
|
||||
PUSH 0 // context
|
||||
// stack: CODE_ADDR, code_len
|
||||
%jump(create)
|
||||
|
||||
process_message_txn:
|
||||
// TODO
|
||||
60
evm/src/cpu/kernel/asm/core/terminate.asm
Normal file
60
evm/src/cpu/kernel/asm/core/terminate.asm
Normal file
@ -0,0 +1,60 @@
|
||||
// Handlers for operations which terminate the current context, namely STOP,
|
||||
// RETURN, SELFDESTRUCT, REVERT, and exceptions such as stack underflow.
|
||||
|
||||
global sys_stop:
|
||||
// TODO: Set parent context's CTX_METADATA_RETURNDATA_SIZE to 0.
|
||||
// TODO: Refund unused gas to parent.
|
||||
%jump(terminate_common)
|
||||
|
||||
global sys_return:
|
||||
// TODO: Set parent context's CTX_METADATA_RETURNDATA_SIZE.
|
||||
// TODO: Copy returned memory to parent context's RETURNDATA (but not if we're returning from a constructor?)
|
||||
// TODO: Copy returned memory to parent context's memory (as specified in their call instruction)
|
||||
// TODO: Refund unused gas to parent.
|
||||
%jump(terminate_common)
|
||||
|
||||
global sys_selfdestruct:
|
||||
%consume_gas_const(@GAS_SELFDESTRUCT)
|
||||
// TODO: Destroy account.
|
||||
// TODO: Refund unused gas to parent.
|
||||
%jump(terminate_common)
|
||||
|
||||
global sys_revert:
|
||||
// TODO: Refund unused gas to parent.
|
||||
// TODO: Revert state changes.
|
||||
%jump(terminate_common)
|
||||
|
||||
// The execution is in an exceptional halt-ing state if
|
||||
// - there is insufficient gas
|
||||
// - the instruction is invalid
|
||||
// - there are insufficient stack items
|
||||
// - a JUMP/JUMPI destination is invalid
|
||||
// - the new stack size would be larger than 1024, or
|
||||
// - state modification is attempted during a static call
|
||||
global fault_exception:
|
||||
// TODO: Revert state changes.
|
||||
%jump(terminate_common)
|
||||
|
||||
terminate_common:
|
||||
// stack: success
|
||||
// We want to move the success flag from our (child) context's stack to the
|
||||
// parent context's stack. We will write it to memory, specifically
|
||||
// SEGMENT_KERNEL_GENERAL[0], then load it after the context switch.
|
||||
PUSH 0
|
||||
// stack: 0, success
|
||||
%mstore_kernel(@SEGMENT_KERNEL_GENERAL)
|
||||
// stack: (empty)
|
||||
|
||||
// Go back to the parent context.
|
||||
%mload_context_metadata(@CTX_METADATA_PARENT_CONTEXT)
|
||||
SET_CONTEXT
|
||||
// stack: (empty)
|
||||
|
||||
// Load the success flag that we stored in SEGMENT_KERNEL_GENERAL[0].
|
||||
PUSH 0
|
||||
%mload_kernel(@SEGMENT_KERNEL_GENERAL)
|
||||
// stack: success
|
||||
|
||||
// JUMP to the parent IP.
|
||||
%mload_context_metadata(@CTX_METADATA_PARENT_PC)
|
||||
JUMP
|
||||
16
evm/src/cpu/kernel/asm/core/transfer.asm
Normal file
16
evm/src/cpu/kernel/asm/core/transfer.asm
Normal file
@ -0,0 +1,16 @@
|
||||
// Transfers some ETH from one address to another. The amount is given in wei.
|
||||
// Pre stack: from, to, amount, retdest
|
||||
// Post stack: (empty)
|
||||
|
||||
global transfer_eth:
|
||||
// stack: from, to, amount, retdest
|
||||
// TODO: Replace with actual implementation.
|
||||
%pop3
|
||||
JUMP
|
||||
|
||||
// Convenience macro to call transfer_eth and return where we left off.
|
||||
%macro transfer_eth
|
||||
%stack (from, to, amount) -> (from, to, amount, %%after)
|
||||
%jump(transfer_eth)
|
||||
%%after:
|
||||
%endmacro
|
||||
32
evm/src/cpu/kernel/asm/core/util.asm
Normal file
32
evm/src/cpu/kernel/asm/core/util.asm
Normal file
@ -0,0 +1,32 @@
|
||||
// Return the next context ID, and record the old context ID in the new one's
|
||||
// @CTX_METADATA_PARENT_CONTEXT field. Does not actually enter the new context.
|
||||
%macro create_context
|
||||
%next_context_id
|
||||
GET_CONTEXT
|
||||
%stack (ctx, next_ctx)
|
||||
-> (next_ctx, @SEGMENT_NORMALIZED_TXN, @CTX_METADATA_PARENT_CONTEXT,
|
||||
ctx, next_ctx)
|
||||
MSTORE_GENERAL
|
||||
// stack: next_ctx
|
||||
%endmacro
|
||||
|
||||
// Get and increment @GLOBAL_METADATA_LARGEST_CONTEXT to determine the next context ID.
|
||||
%macro next_context_id
|
||||
// stack: (empty)
|
||||
%mload_global_metadata(@GLOBAL_METADATA_LARGEST_CONTEXT)
|
||||
%add_const(1)
|
||||
// stack: new_ctx
|
||||
DUP1
|
||||
%mstore_global_metadata(@GLOBAL_METADATA_LARGEST_CONTEXT)
|
||||
// stack: new_ctx
|
||||
%endmacro
|
||||
|
||||
// Returns whether the current transaction is a contract creation transaction.
|
||||
%macro is_contract_creation
|
||||
// stack: (empty)
|
||||
%mload_txn_field(@TXN_FIELD_TO)
|
||||
// stack: to
|
||||
ISZERO
|
||||
// If there is no "to" field, then this is a contract creation.
|
||||
// stack: to == 0
|
||||
%endmacro
|
||||
@ -74,3 +74,6 @@ recursion_return:
|
||||
pop
|
||||
// stack: retdest, (1 + (x - 1) * (e % 2)) * exp(x * x, e / 2)
|
||||
jump
|
||||
|
||||
global sys_exp:
|
||||
PANIC
|
||||
|
||||
8
evm/src/cpu/kernel/asm/keccak.asm
Normal file
8
evm/src/cpu/kernel/asm/keccak.asm
Normal file
@ -0,0 +1,8 @@
|
||||
// Computes the Keccak256 hash of some arbitrary bytes in memory.
|
||||
// The given memory values should be in the range of a byte.
|
||||
//
|
||||
// Pre stack: ADDR, len, retdest
|
||||
// Post stack: hash
|
||||
global keccak_general:
|
||||
// stack: ADDR, len
|
||||
// TODO
|
||||
@ -33,3 +33,15 @@
|
||||
%mload_current(@SEGMENT_CONTEXT_METADATA)
|
||||
// stack: (empty)
|
||||
%endmacro
|
||||
|
||||
%macro address
|
||||
%mload_context_metadata(0) // TODO: Read proper field.
|
||||
%endmacro
|
||||
|
||||
%macro sender
|
||||
%mload_context_metadata(0) // TODO: Read proper field.
|
||||
%endmacro
|
||||
|
||||
%macro callvalue
|
||||
%mload_context_metadata(0) // TODO: Read proper field.
|
||||
%endmacro
|
||||
|
||||
47
evm/src/cpu/kernel/asm/memory/packing.asm
Normal file
47
evm/src/cpu/kernel/asm/memory/packing.asm
Normal file
@ -0,0 +1,47 @@
|
||||
// Methods for encoding integers as bytes in memory, as well as the reverse,
|
||||
// decoding bytes as integers. All big-endian.
|
||||
|
||||
global mload_packing:
|
||||
// stack: context, segment, offset, len, retdest
|
||||
// TODO
|
||||
// stack: value
|
||||
|
||||
// Pre stack: context, segment, offset, value, len, retdest
|
||||
// Post stack: (empty)
|
||||
global mstore_unpacking:
|
||||
// stack: context, segment, offset, value, len, retdest
|
||||
// We will enumerate i in (32 - len)..32.
|
||||
// That way BYTE(i, value) will give us the bytes we want.
|
||||
DUP5 // len
|
||||
PUSH 32
|
||||
SUB
|
||||
|
||||
mstore_unpacking_loop:
|
||||
// stack: i, context, segment, offset, value, len, retdest
|
||||
// If i == 32, finish.
|
||||
DUP1
|
||||
%eq_const(32)
|
||||
%jumpi(mstore_unpacking_finish)
|
||||
|
||||
// stack: i, context, segment, offset, value, len, retdest
|
||||
DUP5 // value
|
||||
DUP2 // i
|
||||
BYTE
|
||||
// stack: value[i], i, context, segment, offset, value, len, retdest
|
||||
DUP5 DUP5 DUP5 // context, segment, offset
|
||||
// stack: context, segment, offset, value[i], i, context, segment, offset, value, len, retdest
|
||||
MSTORE_GENERAL
|
||||
// stack: i, context, segment, offset, value, len, retdest
|
||||
|
||||
// Increment offset.
|
||||
SWAP3 %add_const(1) SWAP3
|
||||
// Increment i.
|
||||
%add_const(1)
|
||||
|
||||
%jump(mstore_unpacking_loop)
|
||||
|
||||
mstore_unpacking_finish:
|
||||
// stack: i, context, segment, offset, value, len, retdest
|
||||
%pop6
|
||||
// stack: retdest
|
||||
JUMP
|
||||
@ -1,17 +1,127 @@
|
||||
// RLP-encode a scalar, i.e. a variable-length integer.
|
||||
// Pre stack: pos, scalar, retdest
|
||||
// Post stack: (empty)
|
||||
// Post stack: pos
|
||||
global encode_rlp_scalar:
|
||||
PANIC // TODO: implement
|
||||
// stack: pos, scalar, retdest
|
||||
// If scalar > 0x7f, this is the "medium" case.
|
||||
DUP2
|
||||
%gt_const(0x7f)
|
||||
%jumpi(encode_rlp_scalar_medium)
|
||||
|
||||
// RLP-encode a fixed-length 160-bit string. Assumes string < 2^160.
|
||||
// This is the "small" case, where the value is its own encoding.
|
||||
// stack: pos, scalar, retdest
|
||||
%stack (pos, scalar) -> (pos, scalar, pos)
|
||||
// stack: pos, scalar, pos, retdest
|
||||
%mstore_current(@SEGMENT_RLP_RAW)
|
||||
// stack: pos, retdest
|
||||
%add_const(1)
|
||||
// stack: pos', retdest
|
||||
SWAP1
|
||||
JUMP
|
||||
|
||||
encode_rlp_scalar_medium:
|
||||
// This is the "medium" case, where we write 0x80 + len followed by the
|
||||
// (big-endian) scalar bytes. We first compute the minimal number of bytes
|
||||
// needed to represent this scalar, then treat it as if it was a fixed-
|
||||
// length string with that length.
|
||||
// stack: pos, scalar, retdest
|
||||
DUP2
|
||||
%num_bytes
|
||||
// stack: scalar_bytes, pos, scalar, retdest
|
||||
%jump(encode_rlp_fixed)
|
||||
|
||||
// Convenience macro to call encode_rlp_scalar and return where we left off.
|
||||
%macro encode_rlp_scalar
|
||||
%stack (pos, scalar) -> (pos, scalar, %%after)
|
||||
%jump(encode_rlp_scalar)
|
||||
%%after:
|
||||
%endmacro
|
||||
|
||||
// RLP-encode a fixed-length 160 bit (20 byte) string. Assumes string < 2^160.
|
||||
// Pre stack: pos, string, retdest
|
||||
// Post stack: (empty)
|
||||
// Post stack: pos
|
||||
global encode_rlp_160:
|
||||
PANIC // TODO: implement
|
||||
PUSH 20
|
||||
%jump(encode_rlp_fixed)
|
||||
|
||||
// RLP-encode a fixed-length 256-bit string.
|
||||
// Convenience macro to call encode_rlp_160 and return where we left off.
|
||||
%macro encode_rlp_160
|
||||
%stack (pos, string) -> (pos, string, %%after)
|
||||
%jump(encode_rlp_160)
|
||||
%%after:
|
||||
%endmacro
|
||||
|
||||
// RLP-encode a fixed-length 256 bit (32 byte) string.
|
||||
// Pre stack: pos, string, retdest
|
||||
// Post stack: (empty)
|
||||
// Post stack: pos
|
||||
global encode_rlp_256:
|
||||
PANIC // TODO: implement
|
||||
PUSH 32
|
||||
%jump(encode_rlp_fixed)
|
||||
|
||||
// Convenience macro to call encode_rlp_256 and return where we left off.
|
||||
%macro encode_rlp_256
|
||||
%stack (pos, string) -> (pos, string, %%after)
|
||||
%jump(encode_rlp_256)
|
||||
%%after:
|
||||
%endmacro
|
||||
|
||||
// RLP-encode a fixed-length string with the given byte length. Assumes string < 2^(8 * len).
|
||||
encode_rlp_fixed:
|
||||
// stack: len, pos, string, retdest
|
||||
DUP1
|
||||
%add_const(0x80)
|
||||
// stack: first_byte, len, pos, string, retdest
|
||||
DUP3
|
||||
// stack: pos, first_byte, len, pos, string, retdest
|
||||
%mstore_current(@SEGMENT_RLP_RAW)
|
||||
// stack: len, pos, string, retdest
|
||||
SWAP1
|
||||
%add_const(1) // increment pos
|
||||
// stack: pos, len, string, retdest
|
||||
%stack (pos, len, string) -> (@SEGMENT_RLP_RAW, pos, string, len, encode_rlp_fixed_finish, pos, len)
|
||||
GET_CONTEXT
|
||||
// stack: context, segment, pos, string, len, encode_rlp_fixed, pos, retdest
|
||||
%jump(mstore_unpacking)
|
||||
|
||||
encode_rlp_fixed_finish:
|
||||
// stack: pos, len, retdest
|
||||
ADD
|
||||
// stack: pos', retdest
|
||||
SWAP1
|
||||
JUMP
|
||||
|
||||
// Get the number of bytes required to represent the given scalar.
|
||||
// The scalar is assumed to be non-zero, as small scalars like zero should
|
||||
// have already been handled with the small-scalar encoding.
|
||||
num_bytes:
|
||||
// stack: x, retdest
|
||||
PUSH 0 // i
|
||||
// stack: i, x, retdest
|
||||
|
||||
num_bytes_loop:
|
||||
// stack: i, x, retdest
|
||||
// If x[i] != 0, break.
|
||||
DUP2 DUP2
|
||||
// stack: i, x, i, x, retdest
|
||||
BYTE
|
||||
// stack: x[i], i, x, retdest
|
||||
%jumpi(num_bytes_finish)
|
||||
// stack: i, x, retdest
|
||||
|
||||
%add_const(1)
|
||||
// stack: i', x, retdest
|
||||
%jump(num_bytes_loop)
|
||||
|
||||
num_bytes_finish:
|
||||
// stack: i, x, retdest
|
||||
PUSH 32
|
||||
SUB
|
||||
%stack (num_bytes, x, retdest) -> (retdest, num_bytes)
|
||||
JUMP
|
||||
|
||||
// Convenience macro to call num_bytes and return where we left off.
|
||||
%macro num_bytes
|
||||
%stack (x) -> (x, %%after)
|
||||
%jump(num_bytes)
|
||||
%%after:
|
||||
%endmacro
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
// After the transaction data has been parsed into a normalized set of fields
|
||||
// (see TxnField), this routine processes the transaction.
|
||||
|
||||
global process_normalized_txn:
|
||||
// TODO
|
||||
@ -23,8 +23,8 @@ global process_type_0_txn:
|
||||
// Decode the nonce and store it.
|
||||
// stack: pos
|
||||
%decode_rlp_scalar
|
||||
%stack (pos, nonce) -> (@TXN_FIELD_NONCE, nonce, pos)
|
||||
%mstore_current(@SEGMENT_NORMALIZED_TXN)
|
||||
%stack (pos, nonce) -> (nonce, pos)
|
||||
%mstore_txn_field(@TXN_FIELD_NONCE)
|
||||
|
||||
// Decode the gas price and store it.
|
||||
// For legacy transactions, we set both the
|
||||
@ -32,34 +32,33 @@ global process_type_0_txn:
|
||||
// fields to gas_price.
|
||||
// stack: pos
|
||||
%decode_rlp_scalar
|
||||
%stack (pos, gas_price) -> (@TXN_FIELD_MAX_PRIORITY_FEE_PER_GAS, gas_price,
|
||||
@TXN_FIELD_MAX_FEE_PER_GAS, gas_price, pos)
|
||||
%mstore_current(@SEGMENT_NORMALIZED_TXN)
|
||||
%mstore_current(@SEGMENT_NORMALIZED_TXN)
|
||||
%stack (pos, gas_price) -> (gas_price, gas_price, pos)
|
||||
%mstore_txn_field(@TXN_FIELD_MAX_PRIORITY_FEE_PER_GAS)
|
||||
%mstore_txn_field(@TXN_FIELD_MAX_FEE_PER_GAS)
|
||||
|
||||
// Decode the gas limit and store it.
|
||||
// stack: pos
|
||||
%decode_rlp_scalar
|
||||
%stack (pos, gas_limit) -> (@TXN_FIELD_GAS_LIMIT, gas_limit, pos)
|
||||
%mstore_current(@SEGMENT_NORMALIZED_TXN)
|
||||
%stack (pos, gas_limit) -> (gas_limit, pos)
|
||||
%mstore_txn_field(@TXN_FIELD_GAS_LIMIT)
|
||||
|
||||
// Decode the "to" field and store it.
|
||||
// stack: pos
|
||||
%decode_rlp_scalar
|
||||
%stack (pos, to) -> (@TXN_FIELD_TO, to, pos)
|
||||
%mstore_current(@SEGMENT_NORMALIZED_TXN)
|
||||
%stack (pos, to) -> (to, pos)
|
||||
%mstore_txn_field(@TXN_FIELD_TO)
|
||||
|
||||
// Decode the value field and store it.
|
||||
// stack: pos
|
||||
%decode_rlp_scalar
|
||||
%stack (pos, value) -> (@TXN_FIELD_VALUE, value, pos)
|
||||
%mstore_current(@SEGMENT_NORMALIZED_TXN)
|
||||
%stack (pos, value) -> (value, pos)
|
||||
%mstore_txn_field(@TXN_FIELD_VALUE)
|
||||
|
||||
// Decode the data length, store it, and compute new_pos after any data.
|
||||
// stack: pos
|
||||
%decode_rlp_string_len
|
||||
%stack (pos, data_len) -> (@TXN_FIELD_DATA_LEN, data_len, pos, data_len, pos, data_len)
|
||||
%mstore_current(@SEGMENT_NORMALIZED_TXN)
|
||||
%stack (pos, data_len) -> (data_len, pos, data_len, pos, data_len)
|
||||
%mstore_txn_field(@TXN_FIELD_DATA_LEN)
|
||||
// stack: pos, data_len, pos, data_len
|
||||
ADD
|
||||
// stack: new_pos, pos, data_len
|
||||
@ -91,8 +90,8 @@ parse_v:
|
||||
// TXN_FIELD_CHAIN_ID with their default values of zero.
|
||||
// stack: v, pos
|
||||
%sub_const(27)
|
||||
%stack (y_parity, pos) -> (@TXN_FIELD_Y_PARITY, y_parity, pos)
|
||||
%mstore_current(@SEGMENT_NORMALIZED_TXN)
|
||||
%stack (y_parity, pos) -> (y_parity, pos)
|
||||
%mstore_txn_field(@TXN_FIELD_Y_PARITY)
|
||||
|
||||
// stack: pos
|
||||
%jump(parse_r)
|
||||
@ -101,8 +100,8 @@ process_v_new_style:
|
||||
// stack: v, pos
|
||||
// We have a new style v, so chain_id_present = 1,
|
||||
// chain_id = (v - 35) / 2, and y_parity = (v - 35) % 2.
|
||||
%stack (v, pos) -> (@TXN_FIELD_CHAIN_ID_PRESENT, 1, v, pos)
|
||||
%mstore_current(@SEGMENT_NORMALIZED_TXN)
|
||||
%stack (v, pos) -> (1, v, pos)
|
||||
%mstore_txn_field(@TXN_FIELD_CHAIN_ID_PRESENT)
|
||||
|
||||
// stack: v, pos
|
||||
%sub_const(35)
|
||||
@ -110,25 +109,23 @@ process_v_new_style:
|
||||
// stack: v - 35, v - 35, pos
|
||||
%div_const(2)
|
||||
// stack: chain_id, v - 35, pos
|
||||
PUSH @TXN_FIELD_CHAIN_ID
|
||||
%mstore_current(@SEGMENT_NORMALIZED_TXN)
|
||||
%mstore_txn_field(@TXN_FIELD_CHAIN_ID)
|
||||
|
||||
// stack: v - 35, pos
|
||||
%mod_const(2)
|
||||
// stack: y_parity, pos
|
||||
PUSH @TXN_FIELD_Y_PARITY
|
||||
%mstore_current(@SEGMENT_NORMALIZED_TXN)
|
||||
%mstore_txn_field(@TXN_FIELD_Y_PARITY)
|
||||
|
||||
parse_r:
|
||||
// stack: pos
|
||||
%decode_rlp_scalar
|
||||
%stack (pos, r) -> (@TXN_FIELD_R, r, pos)
|
||||
%mstore_current(@SEGMENT_NORMALIZED_TXN)
|
||||
%stack (pos, r) -> (r, pos)
|
||||
%mstore_txn_field(@TXN_FIELD_R)
|
||||
|
||||
// stack: pos
|
||||
%decode_rlp_scalar
|
||||
%stack (pos, s) -> (@TXN_FIELD_S, s)
|
||||
%mstore_current(@SEGMENT_NORMALIZED_TXN)
|
||||
%stack (pos, s) -> (s)
|
||||
%mstore_txn_field(@TXN_FIELD_S)
|
||||
// stack: (empty)
|
||||
|
||||
// TODO: Write the signed txn data to memory, where it can be hashed and
|
||||
|
||||
@ -10,7 +10,7 @@ use crate::cpu::kernel::ast::StackReplacement;
|
||||
use crate::cpu::kernel::keccak_util::hash_kernel;
|
||||
use crate::cpu::kernel::optimizer::optimize_asm;
|
||||
use crate::cpu::kernel::prover_input::ProverInputFn;
|
||||
use crate::cpu::kernel::stack_manipulation::expand_stack_manipulation;
|
||||
use crate::cpu::kernel::stack::stack_manipulation::expand_stack_manipulation;
|
||||
use crate::cpu::kernel::utils::u256_to_trimmed_be_bytes;
|
||||
use crate::cpu::kernel::{
|
||||
ast::{File, Item},
|
||||
|
||||
@ -17,10 +17,13 @@ pub(crate) enum ContextMetadata {
|
||||
Caller = 6,
|
||||
/// The value (in wei) deposited by the caller.
|
||||
CallValue = 7,
|
||||
/// Whether this context was created by `STATICCALL`, in which case state changes are
|
||||
/// prohibited.
|
||||
Static = 8,
|
||||
}
|
||||
|
||||
impl ContextMetadata {
|
||||
pub(crate) const COUNT: usize = 8;
|
||||
pub(crate) const COUNT: usize = 9;
|
||||
|
||||
pub(crate) fn all() -> [Self; Self::COUNT] {
|
||||
[
|
||||
@ -32,6 +35,7 @@ impl ContextMetadata {
|
||||
Self::CodeSize,
|
||||
Self::Caller,
|
||||
Self::CallValue,
|
||||
Self::Static,
|
||||
]
|
||||
}
|
||||
|
||||
@ -46,6 +50,7 @@ impl ContextMetadata {
|
||||
ContextMetadata::CodeSize => "CTX_METADATA_CODE_SIZE",
|
||||
ContextMetadata::Caller => "CTX_METADATA_CALLER",
|
||||
ContextMetadata::CallValue => "CTX_METADATA_CALL_VALUE",
|
||||
ContextMetadata::Static => "CTX_METADATA_STATIC",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,15 +134,28 @@ impl<'a> Interpreter<'a> {
|
||||
}
|
||||
|
||||
pub(crate) fn get_txn_field(&self, field: NormalizedTxnField) -> U256 {
|
||||
self.memory.context_memory[0].segments[Segment::TxnFields as usize].content[field as usize]
|
||||
self.memory.context_memory[0].segments[Segment::TxnFields as usize].get(field as usize)
|
||||
}
|
||||
|
||||
pub(crate) fn set_txn_field(&mut self, field: NormalizedTxnField, value: U256) {
|
||||
self.memory.context_memory[0].segments[Segment::TxnFields as usize]
|
||||
.set(field as usize, value);
|
||||
}
|
||||
|
||||
pub(crate) fn get_txn_data(&self) -> &[U256] {
|
||||
&self.memory.context_memory[0].segments[Segment::TxnData as usize].content
|
||||
}
|
||||
|
||||
pub(crate) fn get_rlp_memory(&self) -> Vec<u8> {
|
||||
self.memory.context_memory[self.context].segments[Segment::RlpRaw as usize]
|
||||
.content
|
||||
.iter()
|
||||
.map(|x| x.as_u32() as u8)
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub(crate) fn set_rlp_memory(&mut self, rlp: Vec<u8>) {
|
||||
self.memory.context_memory[0].segments[Segment::RlpRaw as usize].content =
|
||||
self.memory.context_memory[self.context].segments[Segment::RlpRaw as usize].content =
|
||||
rlp.into_iter().map(U256::from).collect();
|
||||
}
|
||||
|
||||
@ -196,7 +209,7 @@ impl<'a> Interpreter<'a> {
|
||||
0x17 => self.run_or(), // "OR",
|
||||
0x18 => self.run_xor(), // "XOR",
|
||||
0x19 => self.run_not(), // "NOT",
|
||||
0x1a => todo!(), // "BYTE",
|
||||
0x1a => self.run_byte(), // "BYTE",
|
||||
0x1b => self.run_shl(), // "SHL",
|
||||
0x1c => todo!(), // "SHR",
|
||||
0x1d => todo!(), // "SAR",
|
||||
@ -380,6 +393,19 @@ impl<'a> Interpreter<'a> {
|
||||
self.push(!x);
|
||||
}
|
||||
|
||||
fn run_byte(&mut self) {
|
||||
let i = self.pop();
|
||||
let x = self.pop();
|
||||
let result = if i > 32.into() {
|
||||
0
|
||||
} else {
|
||||
let mut bytes = [0; 32];
|
||||
x.to_big_endian(&mut bytes);
|
||||
bytes[i.as_usize()]
|
||||
};
|
||||
self.push(result.into());
|
||||
}
|
||||
|
||||
fn run_shl(&mut self) {
|
||||
let shift = self.pop();
|
||||
let x = self.pop();
|
||||
|
||||
@ -10,7 +10,7 @@ mod opcodes;
|
||||
mod optimizer;
|
||||
mod parser;
|
||||
pub mod prover_input;
|
||||
mod stack_manipulation;
|
||||
pub mod stack;
|
||||
mod txn_fields;
|
||||
mod utils;
|
||||
|
||||
|
||||
@ -53,8 +53,8 @@ fn constant_propagation(code: &mut Vec<Item>) {
|
||||
"DIV" => Some(x.checked_div(y).unwrap_or(U256::zero())),
|
||||
"MOD" => Some(x.checked_rem(y).unwrap_or(U256::zero())),
|
||||
"EXP" => Some(x.overflowing_pow(y).0),
|
||||
"SHL" => Some(x << y),
|
||||
"SHR" => Some(x >> y),
|
||||
"SHL" => Some(y << x),
|
||||
"SHR" => Some(y >> x),
|
||||
"AND" => Some(x & y),
|
||||
"OR" => Some(x | y),
|
||||
"XOR" => Some(x ^ y),
|
||||
|
||||
2
evm/src/cpu/kernel/stack/mod.rs
Normal file
2
evm/src/cpu/kernel/stack/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
mod permutations;
|
||||
pub mod stack_manipulation;
|
||||
278
evm/src/cpu/kernel/stack/permutations.rs
Normal file
278
evm/src/cpu/kernel/stack/permutations.rs
Normal file
@ -0,0 +1,278 @@
|
||||
//! This module contains logic for finding the optimal sequence of swaps to get from one stack state
|
||||
//! to another, specifically for the case where the source and destination states are permutations
|
||||
//! of one another.
|
||||
//!
|
||||
//! We solve the problem in three steps:
|
||||
//! 1. Find a permutation `P` such that `P A = B`.
|
||||
//! 2. If `A` contains duplicates, optimize `P` by reducing the number of cycles.
|
||||
//! 3. Convert each cycle into a set of `(0 i)` transpositions, which correspond to swap
|
||||
//! instructions in the EVM.
|
||||
//!
|
||||
//! We typically represent a permutation as a sequence of cycles. For example, the permutation
|
||||
//! `(1 2 3)(1 2)(4 5)` acts as:
|
||||
//!
|
||||
//! ```ignore
|
||||
//! (1 2 3)(1 2)(4 5)[A_0, A_1, A_2, A_3, A_4, A_5] = (1 2 3)(1 2)[A_0, A_1, A_2, A_3, A_5, A_4]
|
||||
//! = (1 2 3)[A_0, A_2, A_1, A_3, A_5, A_4]
|
||||
//! = [A_0, A_3, A_2, A_1, A_5, A_4]
|
||||
//! ```
|
||||
//!
|
||||
//! We typically represent a `(0 i)` transposition as a single scalar `i`.
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::hash::Hash;
|
||||
|
||||
use crate::cpu::kernel::stack::stack_manipulation::{StackItem, StackOp};
|
||||
|
||||
/// Find the optimal sequence of stack operations to get from `src` to `dst`. Assumes that `src` and
|
||||
/// `dst` are permutations of one another.
|
||||
pub(crate) fn get_stack_ops_for_perm(src: &[StackItem], dst: &[StackItem]) -> Vec<StackOp> {
|
||||
// We store stacks with the tip at the end, but the permutation calls below use the opposite
|
||||
// convention. They're a bit simpler when SWAP are (0 i) transposes.
|
||||
let mut src = src.to_vec();
|
||||
let mut dst = dst.to_vec();
|
||||
src.reverse();
|
||||
dst.reverse();
|
||||
|
||||
let perm = find_permutation(&src, &dst);
|
||||
let optimized_perm = combine_cycles(perm, &src);
|
||||
let trans = permutation_to_transpositions(optimized_perm);
|
||||
transpositions_to_stack_ops(trans)
|
||||
}
|
||||
|
||||
/// Apply the given permutation to the given list.
|
||||
#[cfg(test)]
|
||||
fn apply_perm<T: Eq + Hash + Clone>(permutation: Vec<Vec<usize>>, mut lst: Vec<T>) -> Vec<T> {
|
||||
// Run through perm in REVERSE order.
|
||||
for cycl in permutation.iter().rev() {
|
||||
let n = cycl.len();
|
||||
let last = lst[cycl[n - 1]].clone();
|
||||
for i in (0..n - 1).rev() {
|
||||
let j = (i + 1) % n;
|
||||
lst[cycl[j]] = lst[cycl[i]].clone();
|
||||
}
|
||||
lst[cycl[0]] = last;
|
||||
}
|
||||
lst
|
||||
}
|
||||
|
||||
/// This function does STEP 1.
|
||||
/// Given 2 lists A, B find a permutation P such that P . A = B.
|
||||
pub fn find_permutation<T: Eq + Hash + Clone>(lst_a: &[T], lst_b: &[T]) -> Vec<Vec<usize>> {
|
||||
// We should check to ensure that A and B are indeed rearrangments of each other.
|
||||
assert!(is_permutation(lst_a, lst_b));
|
||||
|
||||
let n = lst_a.len();
|
||||
|
||||
// Keep track of the A_i's which have been already placed into the correct position.
|
||||
let mut correct_a = HashSet::new();
|
||||
|
||||
// loc_b is a dictionary where loc_b[b] is the indices i where b = B_i != A_i.
|
||||
// We need to swap appropriate A_j's into these positions.
|
||||
let mut loc_b: HashMap<T, Vec<usize>> = HashMap::new();
|
||||
|
||||
for i in 0..n {
|
||||
if lst_a[i] == lst_b[i] {
|
||||
// If A_i = B_i, we never do SWAP_i as we are already in the correct position.
|
||||
correct_a.insert(i);
|
||||
} else {
|
||||
loc_b.entry(lst_b[i].clone()).or_default().push(i);
|
||||
}
|
||||
}
|
||||
|
||||
// This will be a list of disjoint cycles.
|
||||
let mut permutation = vec![];
|
||||
|
||||
// For technical reasons, it's handy to include [0] as a trivial cycle.
|
||||
// This is because if A_0 = A_i for some other i in a cycle,
|
||||
// we can save transpositions by expanding the cycle to include 0.
|
||||
if correct_a.contains(&0) {
|
||||
permutation.push(vec![0]);
|
||||
}
|
||||
|
||||
for i in 0..n {
|
||||
// If i is both not in the correct position and not already in a cycle, it will start a new cycle.
|
||||
if correct_a.contains(&i) {
|
||||
continue;
|
||||
}
|
||||
|
||||
correct_a.insert(i);
|
||||
let mut cycl = vec![i];
|
||||
|
||||
// lst_a[i] need to be swapped into an index j such that lst_b[j] = lst_a[i].
|
||||
// This exactly means j should be an element of loc_b[lst_a[i]].
|
||||
// We pop as each j should only be used once.
|
||||
// In this step we simply find any permutation. We will improve it to an optimal one in STEP 2.
|
||||
let mut j = loc_b.get_mut(&lst_a[i]).unwrap().pop().unwrap();
|
||||
|
||||
// Keep adding elements to the cycle until we return to our initial index
|
||||
while j != i {
|
||||
correct_a.insert(j);
|
||||
cycl.push(j);
|
||||
j = loc_b.get_mut(&lst_a[j]).unwrap().pop().unwrap();
|
||||
}
|
||||
|
||||
permutation.push(cycl);
|
||||
}
|
||||
permutation
|
||||
}
|
||||
|
||||
/// This function does STEP 2. It tests to see if cycles can be combined which might occur if A has duplicates.
|
||||
fn combine_cycles<T: Eq + Hash + Clone>(mut perm: Vec<Vec<usize>>, lst_a: &[T]) -> Vec<Vec<usize>> {
|
||||
// If perm is a single cycle, there is nothing to combine.
|
||||
if perm.len() == 1 {
|
||||
return perm;
|
||||
}
|
||||
|
||||
let n = lst_a.len();
|
||||
|
||||
// Need a dictionary to keep track of duplicates in lst_a.
|
||||
let mut all_a_positions: HashMap<T, Vec<usize>> = HashMap::new();
|
||||
for i in 0..n {
|
||||
all_a_positions.entry(lst_a[i].clone()).or_default().push(i);
|
||||
}
|
||||
|
||||
// For each element a which occurs at positions i1, ..., ij, combine cycles such that all
|
||||
// ik which occur in a cycle occur in the same cycle.
|
||||
for positions in all_a_positions.values() {
|
||||
if positions.len() == 1 {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut joinedperm = vec![];
|
||||
let mut newperm = vec![];
|
||||
let mut pos = 0;
|
||||
for cycl in perm {
|
||||
// Does cycl include an element of positions?
|
||||
let mut disjoint = true;
|
||||
|
||||
for term in positions {
|
||||
if cycl.contains(term) {
|
||||
if joinedperm.is_empty() {
|
||||
// This is the first cycle we have found including an element of positions.
|
||||
joinedperm = cycl.clone();
|
||||
pos = cycl.iter().position(|x| x == term).unwrap();
|
||||
} else {
|
||||
// Need to merge 2 cycles. If A_i = A_j then the permutations
|
||||
// (C_1, ..., C_k1, i, C_{k1 + 1}, ... C_k2)(D_1, ..., D_k3, j, D_{k3 + 1}, ... D_k4)
|
||||
// (C_1, ..., C_k1, i, D_{k3 + 1}, ... D_k4, D_1, ..., D_k3, j, C_{k1 + 1}, ... C_k2)
|
||||
// lead to the same oupput but the second will require less transpositions.
|
||||
let newpos = cycl.iter().position(|x| x == term).unwrap();
|
||||
joinedperm = [
|
||||
&joinedperm[..pos + 1],
|
||||
&cycl[newpos + 1..],
|
||||
&cycl[..newpos + 1],
|
||||
&joinedperm[pos + 1..],
|
||||
]
|
||||
.concat();
|
||||
}
|
||||
disjoint = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if disjoint {
|
||||
newperm.push(cycl);
|
||||
}
|
||||
}
|
||||
if !joinedperm.is_empty() {
|
||||
newperm.push(joinedperm);
|
||||
}
|
||||
perm = newperm;
|
||||
}
|
||||
perm
|
||||
}
|
||||
|
||||
// This function does STEP 3. Converting all cycles to [0, i] transpositions.
|
||||
fn permutation_to_transpositions(perm: Vec<Vec<usize>>) -> Vec<usize> {
|
||||
let mut trans = vec![];
|
||||
// The method is pretty simple, we have:
|
||||
// (0 C_1 ... C_i) = (0 C_i) ... (0 C_1)
|
||||
// (C_1 ... C_i) = (0 C_1) (0 C_i) ... (0\ C_1).
|
||||
// We simply need to check to see if 0 is in our cycle to see which one to use.
|
||||
for cycl in perm {
|
||||
let n = cycl.len();
|
||||
let zero_pos = cycl.iter().position(|x| *x == 0);
|
||||
if let Some(pos) = zero_pos {
|
||||
trans.extend((1..n).map(|i| cycl[(n + pos - i) % n]));
|
||||
} else {
|
||||
trans.extend((0..=n).map(|i| cycl[(n - i) % n]));
|
||||
}
|
||||
}
|
||||
trans
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn trans_to_perm(trans: Vec<usize>) -> Vec<Vec<usize>> {
|
||||
trans.into_iter().map(|i| vec![0, i]).collect()
|
||||
}
|
||||
|
||||
fn transpositions_to_stack_ops(trans: Vec<usize>) -> Vec<StackOp> {
|
||||
trans.into_iter().map(|i| StackOp::Swap(i as u8)).collect()
|
||||
}
|
||||
|
||||
pub fn is_permutation<T: Eq + Hash + Clone>(a: &[T], b: &[T]) -> bool {
|
||||
make_multiset(a) == make_multiset(b)
|
||||
}
|
||||
|
||||
fn make_multiset<T: Eq + Hash + Clone>(vals: &[T]) -> HashMap<T, usize> {
|
||||
let mut counts = HashMap::new();
|
||||
for val in vals {
|
||||
*counts.entry(val.clone()).or_default() += 1;
|
||||
}
|
||||
counts
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use rand::prelude::SliceRandom;
|
||||
use rand::thread_rng;
|
||||
|
||||
use crate::cpu::kernel::stack::permutations::{
|
||||
apply_perm, combine_cycles, find_permutation, is_permutation,
|
||||
permutation_to_transpositions, trans_to_perm,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn test_combine_cycles() {
|
||||
assert_eq!(
|
||||
combine_cycles(vec![vec![0, 2], vec![3, 4]], &['a', 'b', 'c', 'd', 'a']),
|
||||
vec![vec![0, 3, 4, 2]]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_permutation() {
|
||||
assert!(is_permutation(&['a', 'b', 'c'], &['b', 'c', 'a']));
|
||||
assert!(!is_permutation(&['a', 'b', 'c'], &['a', 'b', 'b', 'c']));
|
||||
assert!(!is_permutation(&['a', 'b', 'c'], &['a', 'd', 'c']));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_all() {
|
||||
let mut test_lst = vec![
|
||||
'a', 'a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'e', 'f', 'g', 'h', 'k',
|
||||
];
|
||||
|
||||
let mut rng = thread_rng();
|
||||
test_lst.shuffle(&mut rng);
|
||||
for _ in 0..1000 {
|
||||
let lst_a = test_lst.clone();
|
||||
test_lst.shuffle(&mut rng);
|
||||
let lst_b = test_lst.clone();
|
||||
|
||||
let perm = find_permutation(&lst_a, &lst_b);
|
||||
assert_eq!(apply_perm(perm.clone(), lst_a.clone()), lst_b);
|
||||
|
||||
let shortperm = combine_cycles(perm.clone(), &lst_a);
|
||||
assert_eq!(apply_perm(shortperm.clone(), lst_a.clone()), lst_b);
|
||||
|
||||
let trans = trans_to_perm(permutation_to_transpositions(perm));
|
||||
assert_eq!(apply_perm(trans.clone(), lst_a.clone()), lst_b);
|
||||
|
||||
let shorttrans = trans_to_perm(permutation_to_transpositions(shortperm));
|
||||
assert_eq!(apply_perm(shorttrans.clone(), lst_a.clone()), lst_b);
|
||||
|
||||
assert!(shorttrans.len() <= trans.len());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,13 +1,15 @@
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
use std::collections::{BinaryHeap, HashMap};
|
||||
use std::hash::Hash;
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::cpu::columns::NUM_CPU_COLUMNS;
|
||||
use crate::cpu::kernel::assembler::BYTES_PER_OFFSET;
|
||||
use crate::cpu::kernel::ast::{Item, PushTarget, StackReplacement};
|
||||
use crate::cpu::kernel::stack_manipulation::StackOp::Pop;
|
||||
use crate::cpu::kernel::stack::permutations::{get_stack_ops_for_perm, is_permutation};
|
||||
use crate::cpu::kernel::stack::stack_manipulation::StackOp::Pop;
|
||||
use crate::cpu::kernel::utils::u256_to_trimmed_be_bytes;
|
||||
use crate::memory;
|
||||
|
||||
@ -164,13 +166,13 @@ impl Ord for Node {
|
||||
|
||||
/// Like `StackReplacement`, but without constants or macro vars, since those were expanded already.
|
||||
#[derive(Eq, PartialEq, Hash, Clone, Debug)]
|
||||
enum StackItem {
|
||||
pub(crate) enum StackItem {
|
||||
NamedItem(String),
|
||||
PushTarget(PushTarget),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
enum StackOp {
|
||||
pub(crate) enum StackOp {
|
||||
Push(PushTarget),
|
||||
Pop,
|
||||
Dup(u8),
|
||||
@ -188,6 +190,11 @@ fn next_ops(
|
||||
return vec![StackOp::Pop]
|
||||
}
|
||||
|
||||
if is_permutation(src, dst) {
|
||||
// The transpositions are right-associative, so the last one gets applied first, hence pop.
|
||||
return vec![get_stack_ops_for_perm(src, dst).pop().unwrap()];
|
||||
}
|
||||
|
||||
let mut ops = vec![StackOp::Pop];
|
||||
|
||||
ops.extend(
|
||||
@ -220,11 +227,31 @@ fn next_ops(
|
||||
.map(StackOp::Dup),
|
||||
);
|
||||
|
||||
ops.extend((1..src_len).map(StackOp::Swap));
|
||||
ops.extend(
|
||||
(1..src_len)
|
||||
.filter(|i| should_try_swap(src, dst, *i))
|
||||
.map(StackOp::Swap),
|
||||
);
|
||||
|
||||
ops
|
||||
}
|
||||
|
||||
/// Whether we should consider `SWAP_i` in the search.
|
||||
fn should_try_swap(src: &[StackItem], dst: &[StackItem], i: u8) -> bool {
|
||||
if src.is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let i = i as usize;
|
||||
let i_from = src.len() - 1;
|
||||
let i_to = i_from - i;
|
||||
|
||||
// Only consider a swap if it places one of the two affected elements in the desired position.
|
||||
let top_correct_pos = i_to < dst.len() && src[i_from] == dst[i_to];
|
||||
let other_correct_pos = i_from < dst.len() && src[i_to] == dst[i_from];
|
||||
top_correct_pos | other_correct_pos
|
||||
}
|
||||
|
||||
impl StackOp {
|
||||
fn cost(&self) -> u32 {
|
||||
let (cpu_rows, memory_rows) = match self {
|
||||
@ -287,3 +314,39 @@ impl StackOp {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV};
|
||||
|
||||
use crate::cpu::kernel::stack::stack_manipulation::StackItem::NamedItem;
|
||||
use crate::cpu::kernel::stack::stack_manipulation::{shortest_path, StackItem};
|
||||
|
||||
#[test]
|
||||
fn test_shortest_path() {
|
||||
init_logger();
|
||||
shortest_path(
|
||||
vec![named("ret"), named("a"), named("b"), named("d")],
|
||||
vec![named("ret"), named("b"), named("a")],
|
||||
vec![],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shortest_path_permutation() {
|
||||
init_logger();
|
||||
shortest_path(
|
||||
vec![named("a"), named("b"), named("c")],
|
||||
vec![named("c"), named("a"), named("b")],
|
||||
vec![],
|
||||
);
|
||||
}
|
||||
|
||||
fn named(name: &str) -> StackItem {
|
||||
NamedItem(name.into())
|
||||
}
|
||||
|
||||
fn init_logger() {
|
||||
let _ = try_init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "debug"));
|
||||
}
|
||||
}
|
||||
54
evm/src/cpu/kernel/tests/core/create_addresses.rs
Normal file
54
evm/src/cpu/kernel/tests/core/create_addresses.rs
Normal file
@ -0,0 +1,54 @@
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::cpu::kernel::aggregator::KERNEL;
|
||||
use crate::cpu::kernel::interpreter::Interpreter;
|
||||
|
||||
#[test]
|
||||
fn test_get_create_address() -> Result<()> {
|
||||
let get_create_address = KERNEL.global_labels["get_create_address"];
|
||||
|
||||
// TODO: Replace with real data once we have a real implementation.
|
||||
let retaddr = 0xdeadbeefu32.into();
|
||||
let nonce = 5.into();
|
||||
let sender = 0.into();
|
||||
let expected_addr = 123.into();
|
||||
|
||||
let initial_stack = vec![retaddr, nonce, sender];
|
||||
let mut interpreter = Interpreter::new_with_kernel(get_create_address, initial_stack);
|
||||
interpreter.run()?;
|
||||
|
||||
assert_eq!(interpreter.stack(), &[expected_addr]);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_create2_address() -> Result<()> {
|
||||
let get_create2_address = KERNEL.global_labels["get_create2_address"];
|
||||
|
||||
// TODO: Replace with real data once we have a real implementation.
|
||||
let retaddr = 0xdeadbeefu32.into();
|
||||
let code_len = 0.into();
|
||||
let code_offset = 0.into();
|
||||
let code_segment = 0.into();
|
||||
let code_context = 0.into();
|
||||
let salt = 5.into();
|
||||
let sender = 0.into();
|
||||
let expected_addr = 123.into();
|
||||
|
||||
let initial_stack = vec![
|
||||
retaddr,
|
||||
code_len,
|
||||
code_offset,
|
||||
code_segment,
|
||||
code_context,
|
||||
salt,
|
||||
sender,
|
||||
];
|
||||
let mut interpreter = Interpreter::new_with_kernel(get_create2_address, initial_stack);
|
||||
interpreter.run()?;
|
||||
|
||||
assert_eq!(interpreter.stack(), &[expected_addr]);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
27
evm/src/cpu/kernel/tests/core/intrinsic_gas.rs
Normal file
27
evm/src/cpu/kernel/tests/core/intrinsic_gas.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::cpu::kernel::aggregator::KERNEL;
|
||||
use crate::cpu::kernel::interpreter::Interpreter;
|
||||
use crate::cpu::kernel::txn_fields::NormalizedTxnField;
|
||||
|
||||
const GAS_TX: u32 = 21_000;
|
||||
const GAS_TXCREATE: u32 = 32_000;
|
||||
|
||||
#[test]
|
||||
fn test_intrinsic_gas() -> Result<()> {
|
||||
let intrinsic_gas = KERNEL.global_labels["intrinsic_gas"];
|
||||
|
||||
// Contract creation transaction.
|
||||
let initial_stack = vec![0xdeadbeefu32.into()];
|
||||
let mut interpreter = Interpreter::new_with_kernel(intrinsic_gas, initial_stack.clone());
|
||||
interpreter.run()?;
|
||||
assert_eq!(interpreter.stack(), vec![(GAS_TX + GAS_TXCREATE).into()]);
|
||||
|
||||
// Message transaction.
|
||||
let mut interpreter = Interpreter::new_with_kernel(intrinsic_gas, initial_stack);
|
||||
interpreter.set_txn_field(NormalizedTxnField::To, 123.into());
|
||||
interpreter.run()?;
|
||||
assert_eq!(interpreter.stack(), vec![GAS_TX.into()]);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
2
evm/src/cpu/kernel/tests/core/mod.rs
Normal file
2
evm/src/cpu/kernel/tests/core/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
mod create_addresses;
|
||||
mod intrinsic_gas;
|
||||
@ -1,6 +1,8 @@
|
||||
mod core;
|
||||
mod curve_ops;
|
||||
mod ecrecover;
|
||||
mod exp;
|
||||
mod packing;
|
||||
mod rlp;
|
||||
mod transaction_parsing;
|
||||
|
||||
|
||||
29
evm/src/cpu/kernel/tests/packing.rs
Normal file
29
evm/src/cpu/kernel/tests/packing.rs
Normal file
@ -0,0 +1,29 @@
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::cpu::kernel::aggregator::KERNEL;
|
||||
use crate::cpu::kernel::interpreter::Interpreter;
|
||||
use crate::memory::segments::Segment;
|
||||
|
||||
#[test]
|
||||
fn test_mstore_unpacking() -> Result<()> {
|
||||
let mstore_unpacking = KERNEL.global_labels["mstore_unpacking"];
|
||||
|
||||
let retdest = 0xDEADBEEFu32.into();
|
||||
let len = 4.into();
|
||||
let value = 0xABCD1234u32.into();
|
||||
let offset = 0.into();
|
||||
let segment = (Segment::TxnData as u32).into();
|
||||
let context = 0.into();
|
||||
let initial_stack = vec![retdest, len, value, offset, segment, context];
|
||||
|
||||
let mut interpreter = Interpreter::new_with_kernel(mstore_unpacking, initial_stack);
|
||||
|
||||
interpreter.run()?;
|
||||
assert_eq!(interpreter.stack(), vec![]);
|
||||
assert_eq!(
|
||||
&interpreter.get_txn_data(),
|
||||
&[0xAB.into(), 0xCD.into(), 0x12.into(), 0x34.into()]
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -3,6 +3,84 @@ use anyhow::Result;
|
||||
use crate::cpu::kernel::aggregator::KERNEL;
|
||||
use crate::cpu::kernel::interpreter::Interpreter;
|
||||
|
||||
#[test]
|
||||
fn test_encode_rlp_scalar_small() -> Result<()> {
|
||||
let encode_rlp_scalar = KERNEL.global_labels["encode_rlp_scalar"];
|
||||
|
||||
let retdest = 0xDEADBEEFu32.into();
|
||||
let scalar = 42.into();
|
||||
let pos = 2.into();
|
||||
let initial_stack = vec![retdest, scalar, pos];
|
||||
let mut interpreter = Interpreter::new_with_kernel(encode_rlp_scalar, initial_stack);
|
||||
|
||||
interpreter.run()?;
|
||||
let expected_stack = vec![3.into()]; // pos' = pos + rlp_len = 2 + 1
|
||||
let expected_rlp = vec![0, 0, 42];
|
||||
assert_eq!(interpreter.stack(), expected_stack);
|
||||
assert_eq!(interpreter.get_rlp_memory(), expected_rlp);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_encode_rlp_scalar_medium() -> Result<()> {
|
||||
let encode_rlp_scalar = KERNEL.global_labels["encode_rlp_scalar"];
|
||||
|
||||
let retdest = 0xDEADBEEFu32.into();
|
||||
let scalar = 0x12345.into();
|
||||
let pos = 2.into();
|
||||
let initial_stack = vec![retdest, scalar, pos];
|
||||
let mut interpreter = Interpreter::new_with_kernel(encode_rlp_scalar, initial_stack);
|
||||
|
||||
interpreter.run()?;
|
||||
let expected_stack = vec![6.into()]; // pos' = pos + rlp_len = 2 + 4
|
||||
let expected_rlp = vec![0, 0, 0x80 + 3, 0x01, 0x23, 0x45];
|
||||
assert_eq!(interpreter.stack(), expected_stack);
|
||||
assert_eq!(interpreter.get_rlp_memory(), expected_rlp);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_encode_rlp_160() -> Result<()> {
|
||||
let encode_rlp_160 = KERNEL.global_labels["encode_rlp_160"];
|
||||
|
||||
let retdest = 0xDEADBEEFu32.into();
|
||||
let string = 0x12345.into();
|
||||
let pos = 0.into();
|
||||
let initial_stack = vec![retdest, string, pos];
|
||||
let mut interpreter = Interpreter::new_with_kernel(encode_rlp_160, initial_stack);
|
||||
|
||||
interpreter.run()?;
|
||||
let expected_stack = vec![(1 + 20).into()]; // pos'
|
||||
#[rustfmt::skip]
|
||||
let expected_rlp = vec![0x80 + 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0x23, 0x45];
|
||||
assert_eq!(interpreter.stack(), expected_stack);
|
||||
assert_eq!(interpreter.get_rlp_memory(), expected_rlp);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_encode_rlp_256() -> Result<()> {
|
||||
let encode_rlp_256 = KERNEL.global_labels["encode_rlp_256"];
|
||||
|
||||
let retdest = 0xDEADBEEFu32.into();
|
||||
let string = 0x12345.into();
|
||||
let pos = 0.into();
|
||||
let initial_stack = vec![retdest, string, pos];
|
||||
let mut interpreter = Interpreter::new_with_kernel(encode_rlp_256, initial_stack);
|
||||
|
||||
interpreter.run()?;
|
||||
let expected_stack = vec![(1 + 32).into()]; // pos'
|
||||
#[rustfmt::skip]
|
||||
let expected_rlp = vec![0x80 + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0x23, 0x45];
|
||||
assert_eq!(interpreter.stack(), expected_stack);
|
||||
assert_eq!(interpreter.get_rlp_memory(), expected_rlp);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decode_rlp_string_len_short() -> Result<()> {
|
||||
let decode_rlp_string_len = KERNEL.global_labels["decode_rlp_string_len"];
|
||||
|
||||
@ -3,6 +3,8 @@ pub(crate) mod columns;
|
||||
mod control_flow;
|
||||
pub mod cpu_stark;
|
||||
pub(crate) mod decode;
|
||||
mod jumps;
|
||||
pub mod kernel;
|
||||
pub mod public_inputs;
|
||||
mod simple_logic;
|
||||
mod syscalls;
|
||||
|
||||
110
evm/src/cpu/syscalls.rs
Normal file
110
evm/src/cpu/syscalls.rs
Normal file
@ -0,0 +1,110 @@
|
||||
//! Handle instructions that are implemented in terms of system calls.
|
||||
//!
|
||||
//! These are usually the ones that are too complicated to implement in one CPU table row.
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
use plonky2::field::extension::Extendable;
|
||||
use plonky2::field::packed::PackedField;
|
||||
use plonky2::field::types::Field;
|
||||
use plonky2::hash::hash_types::RichField;
|
||||
use plonky2::iop::ext_target::ExtensionTarget;
|
||||
|
||||
use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer};
|
||||
use crate::cpu::columns::{CpuColumnsView, COL_MAP};
|
||||
use crate::cpu::kernel::aggregator::KERNEL;
|
||||
|
||||
const NUM_SYSCALLS: usize = 2;
|
||||
|
||||
fn make_syscall_list() -> [(usize, usize); NUM_SYSCALLS] {
|
||||
let kernel = Lazy::force(&KERNEL);
|
||||
[(COL_MAP.is_stop, "sys_stop"), (COL_MAP.is_exp, "sys_exp")]
|
||||
.map(|(col_index, handler_name)| (col_index, kernel.global_labels[handler_name]))
|
||||
}
|
||||
|
||||
static TRAP_LIST: Lazy<[(usize, usize); NUM_SYSCALLS]> = Lazy::new(make_syscall_list);
|
||||
|
||||
pub fn eval_packed<P: PackedField>(
|
||||
lv: &CpuColumnsView<P>,
|
||||
nv: &CpuColumnsView<P>,
|
||||
yield_constr: &mut ConstraintConsumer<P>,
|
||||
) {
|
||||
let lv_syscalls = lv.general.syscalls();
|
||||
let syscall_list = Lazy::force(&TRAP_LIST);
|
||||
// 1 if _any_ syscall, else 0.
|
||||
let should_syscall: P = syscall_list
|
||||
.iter()
|
||||
.map(|&(col_index, _)| lv[col_index])
|
||||
.sum();
|
||||
let filter = lv.is_cpu_cycle * should_syscall;
|
||||
|
||||
// If syscall: set program counter to the handler address
|
||||
// Note that at most one of the `lv[col_index]`s will be 1 and all others will be 0.
|
||||
let syscall_dst: P = syscall_list
|
||||
.iter()
|
||||
.map(|&(col_index, handler_addr)| {
|
||||
lv[col_index] * P::Scalar::from_canonical_usize(handler_addr)
|
||||
})
|
||||
.sum();
|
||||
yield_constr.constraint_transition(filter * (nv.program_counter - syscall_dst));
|
||||
// If syscall: set kernel mode
|
||||
yield_constr.constraint_transition(filter * (nv.is_kernel_mode - P::ONES));
|
||||
// If syscall: push current PC to stack
|
||||
yield_constr.constraint(filter * (lv_syscalls.output[0] - lv.program_counter));
|
||||
// If syscall: push current kernel flag to stack (share register with PC)
|
||||
yield_constr.constraint(filter * (lv_syscalls.output[1] - lv.is_kernel_mode));
|
||||
// If syscall: zero the rest of that register
|
||||
for &limb in &lv_syscalls.output[2..] {
|
||||
yield_constr.constraint(filter * limb);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eval_ext_circuit<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut plonky2::plonk::circuit_builder::CircuitBuilder<F, D>,
|
||||
lv: &CpuColumnsView<ExtensionTarget<D>>,
|
||||
nv: &CpuColumnsView<ExtensionTarget<D>>,
|
||||
yield_constr: &mut RecursiveConstraintConsumer<F, D>,
|
||||
) {
|
||||
let lv_syscalls = lv.general.syscalls();
|
||||
let syscall_list = Lazy::force(&TRAP_LIST);
|
||||
// 1 if _any_ syscall, else 0.
|
||||
let should_syscall =
|
||||
builder.add_many_extension(syscall_list.iter().map(|&(col_index, _)| lv[col_index]));
|
||||
let filter = builder.mul_extension(lv.is_cpu_cycle, should_syscall);
|
||||
|
||||
// If syscall: set program counter to the handler address
|
||||
{
|
||||
// Note that at most one of the `lv[col_index]`s will be 1 and all others will be 0.
|
||||
let syscall_dst = syscall_list.iter().fold(
|
||||
builder.zero_extension(),
|
||||
|cumul, &(col_index, handler_addr)| {
|
||||
let handler_addr = F::from_canonical_usize(handler_addr);
|
||||
builder.mul_const_add_extension(handler_addr, lv[col_index], cumul)
|
||||
},
|
||||
);
|
||||
let constr = builder.sub_extension(nv.program_counter, syscall_dst);
|
||||
let constr = builder.mul_extension(filter, constr);
|
||||
yield_constr.constraint_transition(builder, constr);
|
||||
}
|
||||
// If syscall: set kernel mode
|
||||
{
|
||||
let constr = builder.mul_sub_extension(filter, nv.is_kernel_mode, filter);
|
||||
yield_constr.constraint_transition(builder, constr);
|
||||
}
|
||||
// If syscall: push current PC to stack
|
||||
{
|
||||
let constr = builder.sub_extension(lv_syscalls.output[0], lv.program_counter);
|
||||
let constr = builder.mul_extension(filter, constr);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
// If syscall: push current kernel flag to stack (share register with PC)
|
||||
{
|
||||
let constr = builder.sub_extension(lv_syscalls.output[1], lv.is_kernel_mode);
|
||||
let constr = builder.mul_extension(filter, constr);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
// If syscall: zero the rest of that register
|
||||
for &limb in &lv_syscalls.output[2..] {
|
||||
let constr = builder.mul_extension(filter, limb);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
}
|
||||
@ -14,9 +14,12 @@ pub const fn reg_step(i: usize) -> usize {
|
||||
/// `reg_input_limb(2*i+1) -> input[i] >> 32`
|
||||
pub fn reg_input_limb<F: Field>(i: usize) -> Column<F> {
|
||||
debug_assert!(i < 2 * NUM_INPUTS);
|
||||
let range = if i % 2 == 0 { 0..32 } else { 32..64 };
|
||||
let bits = range.map(|j| reg_a((i / 2) / 5, (i / 2) % 5, j));
|
||||
Column::le_bits(bits)
|
||||
let i_u64 = i / 2; // The index of the 64-bit chunk.
|
||||
let x = i_u64 / 5;
|
||||
let y = i_u64 % 5;
|
||||
let reg_low_limb = reg_a(x, y);
|
||||
let is_high_limb = i % 2;
|
||||
Column::single(reg_low_limb + is_high_limb)
|
||||
}
|
||||
|
||||
/// Registers to hold permutation outputs.
|
||||
@ -24,14 +27,11 @@ pub fn reg_input_limb<F: Field>(i: usize) -> Column<F> {
|
||||
/// `reg_output_limb(2*i+1) -> output[i] >> 32`
|
||||
pub const fn reg_output_limb(i: usize) -> usize {
|
||||
debug_assert!(i < 2 * NUM_INPUTS);
|
||||
let ii = i / 2;
|
||||
let x = ii / 5;
|
||||
let y = ii % 5;
|
||||
if i % 2 == 0 {
|
||||
reg_a_prime_prime_prime(x, y)
|
||||
} else {
|
||||
reg_a_prime_prime_prime(x, y) + 1
|
||||
}
|
||||
let i_u64 = i / 2; // The index of the 64-bit chunk.
|
||||
let x = i_u64 / 5;
|
||||
let y = i_u64 % 5;
|
||||
let is_high_limb = i % 2;
|
||||
reg_a_prime_prime_prime(x, y) + is_high_limb
|
||||
}
|
||||
|
||||
const R: [[u8; 5]; 5] = [
|
||||
@ -43,31 +43,33 @@ const R: [[u8; 5]; 5] = [
|
||||
];
|
||||
|
||||
const START_A: usize = NUM_ROUNDS;
|
||||
pub(crate) const fn reg_a(x: usize, y: usize, z: usize) -> usize {
|
||||
pub(crate) const fn reg_a(x: usize, y: usize) -> usize {
|
||||
debug_assert!(x < 5);
|
||||
debug_assert!(y < 5);
|
||||
debug_assert!(z < 64);
|
||||
START_A + x * 64 * 5 + y * 64 + z
|
||||
START_A + (x * 5 + y) * 2
|
||||
}
|
||||
|
||||
// C_partial[x] = xor(A[x, 0], A[x, 1], A[x, 2])
|
||||
const START_C_PARTIAL: usize = START_A + 5 * 5 * 64;
|
||||
pub(crate) const fn reg_c_partial(x: usize, z: usize) -> usize {
|
||||
START_C_PARTIAL + x * 64 + z
|
||||
}
|
||||
|
||||
// C[x] = xor(C_partial[x], A[x, 3], A[x, 4])
|
||||
const START_C: usize = START_C_PARTIAL + 5 * 64;
|
||||
// C[x] = xor(A[x, 0], A[x, 1], A[x, 2], A[x, 3], A[x, 4])
|
||||
const START_C: usize = START_A + 5 * 5 * 2;
|
||||
pub(crate) const fn reg_c(x: usize, z: usize) -> usize {
|
||||
debug_assert!(x < 5);
|
||||
debug_assert!(z < 64);
|
||||
START_C + x * 64 + z
|
||||
}
|
||||
|
||||
// D is inlined.
|
||||
// const fn reg_d(x: usize, z: usize) {}
|
||||
// C'[x, z] = xor(C[x, z], C[x - 1, z], C[x + 1, z - 1])
|
||||
const START_C_PRIME: usize = START_C + 5 * 64;
|
||||
pub(crate) const fn reg_c_prime(x: usize, z: usize) -> usize {
|
||||
debug_assert!(x < 5);
|
||||
debug_assert!(z < 64);
|
||||
START_C_PRIME + x * 64 + z
|
||||
}
|
||||
|
||||
// Note: D is inlined, not stored in the witness.
|
||||
|
||||
// A'[x, y] = xor(A[x, y], D[x])
|
||||
// = xor(A[x, y], C[x - 1], ROT(C[x + 1], 1))
|
||||
const START_A_PRIME: usize = START_C + 5 * 64;
|
||||
const START_A_PRIME: usize = START_C_PRIME + 5 * 64;
|
||||
pub(crate) const fn reg_a_prime(x: usize, y: usize, z: usize) -> usize {
|
||||
debug_assert!(x < 5);
|
||||
debug_assert!(y < 5);
|
||||
|
||||
@ -15,7 +15,7 @@ use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer
|
||||
use crate::cross_table_lookup::Column;
|
||||
use crate::keccak::columns::{
|
||||
reg_a, reg_a_prime, reg_a_prime_prime, reg_a_prime_prime_0_0_bit, reg_a_prime_prime_prime,
|
||||
reg_b, reg_c, reg_c_partial, reg_input_limb, reg_output_limb, reg_step, NUM_COLUMNS,
|
||||
reg_b, reg_c, reg_c_prime, reg_input_limb, reg_output_limb, reg_step, NUM_COLUMNS,
|
||||
};
|
||||
use crate::keccak::constants::{rc_value, rc_value_bit};
|
||||
use crate::keccak::logic::{
|
||||
@ -77,9 +77,10 @@ impl<F: RichField + Extendable<D>, const D: usize> KeccakStark<F, D> {
|
||||
for x in 0..5 {
|
||||
for y in 0..5 {
|
||||
let input_xy = input[x * 5 + y];
|
||||
for z in 0..64 {
|
||||
rows[0][reg_a(x, y, z)] = F::from_canonical_u64((input_xy >> z) & 1);
|
||||
}
|
||||
let reg_lo = reg_a(x, y);
|
||||
let reg_hi = reg_lo + 1;
|
||||
rows[0][reg_lo] = F::from_canonical_u64(input_xy & 0xFFFFFFFF);
|
||||
rows[0][reg_hi] = F::from_canonical_u64(input_xy >> 32);
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,20 +96,12 @@ impl<F: RichField + Extendable<D>, const D: usize> KeccakStark<F, D> {
|
||||
fn copy_output_to_input(&self, prev_row: [F; NUM_COLUMNS], next_row: &mut [F; NUM_COLUMNS]) {
|
||||
for x in 0..5 {
|
||||
for y in 0..5 {
|
||||
let cur_lo = prev_row[reg_a_prime_prime_prime(x, y)];
|
||||
let cur_hi = prev_row[reg_a_prime_prime_prime(x, y) + 1];
|
||||
let cur_u64 = cur_lo.to_canonical_u64() | (cur_hi.to_canonical_u64() << 32);
|
||||
let bit_values: Vec<u64> = (0..64)
|
||||
.scan(cur_u64, |acc, _| {
|
||||
let tmp = *acc & 1;
|
||||
*acc >>= 1;
|
||||
Some(tmp)
|
||||
})
|
||||
.collect();
|
||||
|
||||
for z in 0..64 {
|
||||
next_row[reg_a(x, y, z)] = F::from_canonical_u64(bit_values[z]);
|
||||
}
|
||||
let in_lo = reg_a(x, y);
|
||||
let in_hi = in_lo + 1;
|
||||
let out_lo = reg_a_prime_prime_prime(x, y);
|
||||
let out_hi = out_lo + 1;
|
||||
next_row[in_lo] = prev_row[out_lo];
|
||||
next_row[in_hi] = prev_row[out_hi];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -116,14 +109,28 @@ impl<F: RichField + Extendable<D>, const D: usize> KeccakStark<F, D> {
|
||||
fn generate_trace_row_for_round(&self, row: &mut [F; NUM_COLUMNS], round: usize) {
|
||||
row[reg_step(round)] = F::ONE;
|
||||
|
||||
// Populate C partial and C.
|
||||
// Populate C[x] = xor(A[x, 0], A[x, 1], A[x, 2], A[x, 3], A[x, 4]).
|
||||
for x in 0..5 {
|
||||
for z in 0..64 {
|
||||
let a = [0, 1, 2, 3, 4].map(|i| row[reg_a(x, i, z)]);
|
||||
let c_partial = xor([a[0], a[1], a[2]]);
|
||||
let c = xor([c_partial, a[3], a[4]]);
|
||||
row[reg_c_partial(x, z)] = c_partial;
|
||||
row[reg_c(x, z)] = c;
|
||||
let is_high_limb = z / 32;
|
||||
let bit_in_limb = z % 32;
|
||||
let a = [0, 1, 2, 3, 4].map(|i| {
|
||||
let reg_a_limb = reg_a(x, i) + is_high_limb;
|
||||
let a_limb = row[reg_a_limb].to_canonical_u64() as u32;
|
||||
F::from_bool(((a_limb >> bit_in_limb) & 1) != 0)
|
||||
});
|
||||
row[reg_c(x, z)] = xor(a);
|
||||
}
|
||||
}
|
||||
|
||||
// Populate C'[x, z] = xor(C[x, z], C[x - 1, z], C[x + 1, z - 1]).
|
||||
for x in 0..5 {
|
||||
for z in 0..64 {
|
||||
row[reg_c_prime(x, z)] = xor([
|
||||
row[reg_c(x, z)],
|
||||
row[reg_c((x + 4) % 5, z)],
|
||||
row[reg_c((x + 1) % 5, (z + 63) % 64)],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,8 +140,13 @@ impl<F: RichField + Extendable<D>, const D: usize> KeccakStark<F, D> {
|
||||
for x in 0..5 {
|
||||
for y in 0..5 {
|
||||
for z in 0..64 {
|
||||
let is_high_limb = z / 32;
|
||||
let bit_in_limb = z % 32;
|
||||
let reg_a_limb = reg_a(x, y) + is_high_limb;
|
||||
let a_limb = row[reg_a_limb].to_canonical_u64() as u32;
|
||||
let a_bit = F::from_bool(((a_limb >> bit_in_limb) & 1) != 0);
|
||||
row[reg_a_prime(x, y, z)] = xor([
|
||||
row[reg_a(x, y, z)],
|
||||
a_bit,
|
||||
row[reg_c((x + 4) % 5, z)],
|
||||
row[reg_c((x + 1) % 5, (z + 64 - 1) % 64)],
|
||||
]);
|
||||
@ -228,44 +240,58 @@ impl<F: RichField + Extendable<D>, const D: usize> Stark<F, D> for KeccakStark<F
|
||||
{
|
||||
eval_round_flags(vars, yield_constr);
|
||||
|
||||
// C_partial[x] = xor(A[x, 0], A[x, 1], A[x, 2])
|
||||
// C'[x, z] = xor(C[x, z], C[x - 1, z], C[x + 1, z - 1]).
|
||||
for x in 0..5 {
|
||||
for z in 0..64 {
|
||||
let c_partial = vars.local_values[reg_c_partial(x, z)];
|
||||
let a_0 = vars.local_values[reg_a(x, 0, z)];
|
||||
let a_1 = vars.local_values[reg_a(x, 1, z)];
|
||||
let a_2 = vars.local_values[reg_a(x, 2, z)];
|
||||
let xor_012 = xor3_gen(a_0, a_1, a_2);
|
||||
yield_constr.constraint(c_partial - xor_012);
|
||||
let xor = xor3_gen(
|
||||
vars.local_values[reg_c(x, z)],
|
||||
vars.local_values[reg_c((x + 4) % 5, z)],
|
||||
vars.local_values[reg_c((x + 1) % 5, (z + 63) % 64)],
|
||||
);
|
||||
let c_prime = vars.local_values[reg_c_prime(x, z)];
|
||||
yield_constr.constraint(c_prime - xor);
|
||||
}
|
||||
}
|
||||
|
||||
// C[x] = xor(C_partial[x], A[x, 3], A[x, 4])
|
||||
// Check that the input limbs are consistent with A' and D.
|
||||
// A[x, y, z] = xor(A'[x, y, z], D[x, y, z])
|
||||
// = xor(A'[x, y, z], C[x - 1, z], C[x + 1, z - 1])
|
||||
// = xor(A'[x, y, z], C[x, z], C'[x, z]).
|
||||
// The last step is valid based on the identity we checked above.
|
||||
// It isn't required, but makes this check a bit cleaner.
|
||||
for x in 0..5 {
|
||||
for z in 0..64 {
|
||||
let c = vars.local_values[reg_c(x, z)];
|
||||
let xor_012 = vars.local_values[reg_c_partial(x, z)];
|
||||
let a_3 = vars.local_values[reg_a(x, 3, z)];
|
||||
let a_4 = vars.local_values[reg_a(x, 4, z)];
|
||||
let xor_01234 = xor3_gen(xor_012, a_3, a_4);
|
||||
yield_constr.constraint(c - xor_01234);
|
||||
}
|
||||
}
|
||||
|
||||
// A'[x, y] = xor(A[x, y], D[x])
|
||||
// = xor(A[x, y], C[x - 1], ROT(C[x + 1], 1))
|
||||
for x in 0..5 {
|
||||
for z in 0..64 {
|
||||
let c_left = vars.local_values[reg_c((x + 4) % 5, z)];
|
||||
let c_right = vars.local_values[reg_c((x + 1) % 5, (z + 64 - 1) % 64)];
|
||||
let d = xor_gen(c_left, c_right);
|
||||
|
||||
for y in 0..5 {
|
||||
let a = vars.local_values[reg_a(x, y, z)];
|
||||
for y in 0..5 {
|
||||
let a_lo = vars.local_values[reg_a(x, y)];
|
||||
let a_hi = vars.local_values[reg_a(x, y) + 1];
|
||||
let get_bit = |z| {
|
||||
let a_prime = vars.local_values[reg_a_prime(x, y, z)];
|
||||
let xor = xor_gen(d, a);
|
||||
yield_constr.constraint(a_prime - xor);
|
||||
}
|
||||
let c = vars.local_values[reg_c(x, z)];
|
||||
let c_prime = vars.local_values[reg_c_prime(x, z)];
|
||||
xor3_gen(a_prime, c, c_prime)
|
||||
};
|
||||
let computed_lo = (0..32)
|
||||
.rev()
|
||||
.fold(P::ZEROS, |acc, z| acc.doubles() + get_bit(z));
|
||||
let computed_hi = (32..64)
|
||||
.rev()
|
||||
.fold(P::ZEROS, |acc, z| acc.doubles() + get_bit(z));
|
||||
yield_constr.constraint(computed_lo - a_lo);
|
||||
yield_constr.constraint(computed_hi - a_hi);
|
||||
}
|
||||
}
|
||||
|
||||
// xor_{i=0}^4 A'[x, i, z] = C'[x, z], so for each x, z,
|
||||
// diff * (diff - 2) * (diff - 4) = 0, where
|
||||
// diff = sum_{i=0}^4 A'[x, i, z] - C'[x, z]
|
||||
for x in 0..5 {
|
||||
for z in 0..64 {
|
||||
let sum: P = [0, 1, 2, 3, 4]
|
||||
.map(|i| vars.local_values[reg_a_prime(x, i, z)])
|
||||
.into_iter()
|
||||
.sum();
|
||||
let diff = sum - vars.local_values[reg_c_prime(x, z)];
|
||||
yield_constr
|
||||
.constraint(diff * (diff - FE::TWO) * (diff - FE::from_canonical_u8(4)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -341,22 +367,12 @@ impl<F: RichField + Extendable<D>, const D: usize> Stark<F, D> for KeccakStark<F
|
||||
for y in 0..5 {
|
||||
let output_lo = vars.local_values[reg_a_prime_prime_prime(x, y)];
|
||||
let output_hi = vars.local_values[reg_a_prime_prime_prime(x, y) + 1];
|
||||
let input_bits = (0..64)
|
||||
.map(|z| vars.next_values[reg_a(x, y, z)])
|
||||
.collect_vec();
|
||||
let input_bits_combined_lo = (0..32)
|
||||
.rev()
|
||||
.fold(P::ZEROS, |acc, z| acc.doubles() + input_bits[z]);
|
||||
let input_bits_combined_hi = (32..64)
|
||||
.rev()
|
||||
.fold(P::ZEROS, |acc, z| acc.doubles() + input_bits[z]);
|
||||
let input_lo = vars.next_values[reg_a(x, y)];
|
||||
let input_hi = vars.next_values[reg_a(x, y) + 1];
|
||||
let is_last_round = vars.local_values[reg_step(NUM_ROUNDS - 1)];
|
||||
yield_constr.constraint_transition(
|
||||
(P::ONES - is_last_round) * (output_lo - input_bits_combined_lo),
|
||||
);
|
||||
yield_constr.constraint_transition(
|
||||
(P::ONES - is_last_round) * (output_hi - input_bits_combined_hi),
|
||||
);
|
||||
let not_last_round = P::ONES - is_last_round;
|
||||
yield_constr.constraint_transition(not_last_round * (output_lo - input_lo));
|
||||
yield_constr.constraint_transition(not_last_round * (output_hi - input_hi));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -368,52 +384,67 @@ impl<F: RichField + Extendable<D>, const D: usize> Stark<F, D> for KeccakStark<F
|
||||
yield_constr: &mut RecursiveConstraintConsumer<F, D>,
|
||||
) {
|
||||
let two = builder.two();
|
||||
let two_ext = builder.two_extension();
|
||||
let four_ext = builder.constant_extension(F::Extension::from_canonical_u8(4));
|
||||
|
||||
eval_round_flags_recursively(builder, vars, yield_constr);
|
||||
|
||||
// C_partial[x] = xor(A[x, 0], A[x, 1], A[x, 2])
|
||||
// C'[x, z] = xor(C[x, z], C[x - 1, z], C[x + 1, z - 1]).
|
||||
for x in 0..5 {
|
||||
for z in 0..64 {
|
||||
let c_partial = vars.local_values[reg_c_partial(x, z)];
|
||||
let a_0 = vars.local_values[reg_a(x, 0, z)];
|
||||
let a_1 = vars.local_values[reg_a(x, 1, z)];
|
||||
let a_2 = vars.local_values[reg_a(x, 2, z)];
|
||||
|
||||
let xor_012 = xor3_gen_circuit(builder, a_0, a_1, a_2);
|
||||
let diff = builder.sub_extension(c_partial, xor_012);
|
||||
let xor = xor3_gen_circuit(
|
||||
builder,
|
||||
vars.local_values[reg_c(x, z)],
|
||||
vars.local_values[reg_c((x + 4) % 5, z)],
|
||||
vars.local_values[reg_c((x + 1) % 5, (z + 63) % 64)],
|
||||
);
|
||||
let c_prime = vars.local_values[reg_c_prime(x, z)];
|
||||
let diff = builder.sub_extension(c_prime, xor);
|
||||
yield_constr.constraint(builder, diff);
|
||||
}
|
||||
}
|
||||
|
||||
// C[x] = xor(C_partial[x], A[x, 3], A[x, 4])
|
||||
// Check that the input limbs are consistent with A' and D.
|
||||
// A[x, y, z] = xor(A'[x, y, z], D[x, y, z])
|
||||
// = xor(A'[x, y, z], C[x - 1, z], C[x + 1, z - 1])
|
||||
// = xor(A'[x, y, z], C[x, z], C'[x, z]).
|
||||
// The last step is valid based on the identity we checked above.
|
||||
// It isn't required, but makes this check a bit cleaner.
|
||||
for x in 0..5 {
|
||||
for z in 0..64 {
|
||||
let c = vars.local_values[reg_c(x, z)];
|
||||
let xor_012 = vars.local_values[reg_c_partial(x, z)];
|
||||
let a_3 = vars.local_values[reg_a(x, 3, z)];
|
||||
let a_4 = vars.local_values[reg_a(x, 4, z)];
|
||||
|
||||
let xor_01234 = xor3_gen_circuit(builder, xor_012, a_3, a_4);
|
||||
let diff = builder.sub_extension(c, xor_01234);
|
||||
yield_constr.constraint(builder, diff);
|
||||
}
|
||||
}
|
||||
|
||||
// A'[x, y] = xor(A[x, y], D[x])
|
||||
// = xor(A[x, y], C[x - 1], ROT(C[x + 1], 1))
|
||||
for x in 0..5 {
|
||||
for z in 0..64 {
|
||||
let c_left = vars.local_values[reg_c((x + 4) % 5, z)];
|
||||
let c_right = vars.local_values[reg_c((x + 1) % 5, (z + 64 - 1) % 64)];
|
||||
let d = xor_gen_circuit(builder, c_left, c_right);
|
||||
|
||||
for y in 0..5 {
|
||||
let a = vars.local_values[reg_a(x, y, z)];
|
||||
for y in 0..5 {
|
||||
let a_lo = vars.local_values[reg_a(x, y)];
|
||||
let a_hi = vars.local_values[reg_a(x, y) + 1];
|
||||
let mut get_bit = |z| {
|
||||
let a_prime = vars.local_values[reg_a_prime(x, y, z)];
|
||||
let xor = xor_gen_circuit(builder, d, a);
|
||||
let diff = builder.sub_extension(a_prime, xor);
|
||||
yield_constr.constraint(builder, diff);
|
||||
}
|
||||
let c = vars.local_values[reg_c(x, z)];
|
||||
let c_prime = vars.local_values[reg_c_prime(x, z)];
|
||||
xor3_gen_circuit(builder, a_prime, c, c_prime)
|
||||
};
|
||||
let bits_lo = (0..32).map(&mut get_bit).collect_vec();
|
||||
let bits_hi = (32..64).map(get_bit).collect_vec();
|
||||
let computed_lo = reduce_with_powers_ext_circuit(builder, &bits_lo, two);
|
||||
let computed_hi = reduce_with_powers_ext_circuit(builder, &bits_hi, two);
|
||||
let diff = builder.sub_extension(computed_lo, a_lo);
|
||||
yield_constr.constraint(builder, diff);
|
||||
let diff = builder.sub_extension(computed_hi, a_hi);
|
||||
yield_constr.constraint(builder, diff);
|
||||
}
|
||||
}
|
||||
|
||||
// xor_{i=0}^4 A'[x, i, z] = C'[x, z], so for each x, z,
|
||||
// diff * (diff - 2) * (diff - 4) = 0, where
|
||||
// diff = sum_{i=0}^4 A'[x, i, z] - C'[x, z]
|
||||
for x in 0..5 {
|
||||
for z in 0..64 {
|
||||
let sum = builder.add_many_extension(
|
||||
[0, 1, 2, 3, 4].map(|i| vars.local_values[reg_a_prime(x, i, z)]),
|
||||
);
|
||||
let diff = builder.sub_extension(sum, vars.local_values[reg_c_prime(x, z)]);
|
||||
let diff_minus_two = builder.sub_extension(diff, two_ext);
|
||||
let diff_minus_four = builder.sub_extension(diff, four_ext);
|
||||
let constraint =
|
||||
builder.mul_many_extension([diff, diff_minus_two, diff_minus_four]);
|
||||
yield_constr.constraint(builder, constraint);
|
||||
}
|
||||
}
|
||||
|
||||
@ -495,18 +526,13 @@ impl<F: RichField + Extendable<D>, const D: usize> Stark<F, D> for KeccakStark<F
|
||||
for y in 0..5 {
|
||||
let output_lo = vars.local_values[reg_a_prime_prime_prime(x, y)];
|
||||
let output_hi = vars.local_values[reg_a_prime_prime_prime(x, y) + 1];
|
||||
let input_bits = (0..64)
|
||||
.map(|z| vars.next_values[reg_a(x, y, z)])
|
||||
.collect_vec();
|
||||
let input_bits_combined_lo =
|
||||
reduce_with_powers_ext_circuit(builder, &input_bits[0..32], two);
|
||||
let input_bits_combined_hi =
|
||||
reduce_with_powers_ext_circuit(builder, &input_bits[32..64], two);
|
||||
let input_lo = vars.next_values[reg_a(x, y)];
|
||||
let input_hi = vars.next_values[reg_a(x, y) + 1];
|
||||
let is_last_round = vars.local_values[reg_step(NUM_ROUNDS - 1)];
|
||||
let diff = builder.sub_extension(input_bits_combined_lo, output_lo);
|
||||
let diff = builder.sub_extension(input_lo, output_lo);
|
||||
let filtered_diff = builder.mul_sub_extension(is_last_round, diff, diff);
|
||||
yield_constr.constraint_transition(builder, filtered_diff);
|
||||
let diff = builder.sub_extension(input_bits_combined_hi, output_hi);
|
||||
let diff = builder.sub_extension(input_hi, output_hi);
|
||||
let filtered_diff = builder.mul_sub_extension(is_last_round, diff, diff);
|
||||
yield_constr.constraint_transition(builder, filtered_diff);
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ pub(crate) enum Segment {
|
||||
/// General purpose kernel memory, used by various kernel functions.
|
||||
/// In general, calling a helper function can result in this memory being clobbered.
|
||||
KernelGeneral = 7,
|
||||
/// Contains normalized transaction fields; see `TxnField`.
|
||||
/// Contains normalized transaction fields; see `NormalizedTxnField`.
|
||||
TxnFields = 8,
|
||||
/// Contains the data field of a transaction.
|
||||
TxnData = 9,
|
||||
|
||||
202
field/LICENSE-APACHE
Normal file
202
field/LICENSE-APACHE
Normal file
@ -0,0 +1,202 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
21
field/LICENSE-MIT
Normal file
21
field/LICENSE-MIT
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2022 The Plonky2 Authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
13
field/README.md
Normal file
13
field/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
## License
|
||||
|
||||
Licensed under either of
|
||||
|
||||
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
||||
|
||||
at your option.
|
||||
|
||||
|
||||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
|
||||
@ -192,10 +192,17 @@ pub trait Field:
|
||||
/// Compute the inverse of 2^exp in this field.
|
||||
#[inline]
|
||||
fn inverse_2exp(exp: usize) -> Self {
|
||||
// The inverse of 2^exp is p-(p-1)/2^exp when char(F) = p and
|
||||
// exp is at most the t=TWO_ADICITY of the prime field. When
|
||||
// exp exceeds t, we repeatedly multiply by 2^-t and reduce
|
||||
// exp until it's in the right range.
|
||||
// Let p = char(F). Since 2^exp is in the prime subfield, i.e. an
|
||||
// element of GF_p, its inverse must be as well. Thus we may add
|
||||
// multiples of p without changing the result. In particular,
|
||||
// 2^-exp = 2^-exp - p 2^-exp
|
||||
// = 2^-exp (1 - p)
|
||||
// = p - (p - 1) / 2^exp
|
||||
|
||||
// If this field's two adicity, t, is at least exp, then 2^exp divides
|
||||
// p - 1, so this division can be done with a simple bit shift. If
|
||||
// exp > t, we repeatedly multiply by 2^-t and reduce exp until it's in
|
||||
// the right range.
|
||||
|
||||
if let Some(p) = Self::characteristic().to_u64() {
|
||||
// NB: The only reason this is split into two cases is to save
|
||||
|
||||
202
insertion/LICENSE-APACHE
Normal file
202
insertion/LICENSE-APACHE
Normal file
@ -0,0 +1,202 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
21
insertion/LICENSE-MIT
Normal file
21
insertion/LICENSE-MIT
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2022 The Plonky2 Authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
13
insertion/README.md
Normal file
13
insertion/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
## License
|
||||
|
||||
Licensed under either of
|
||||
|
||||
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
||||
|
||||
at your option.
|
||||
|
||||
|
||||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
|
||||
202
maybe_rayon/LICENSE-APACHE
Normal file
202
maybe_rayon/LICENSE-APACHE
Normal file
@ -0,0 +1,202 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
21
maybe_rayon/LICENSE-MIT
Normal file
21
maybe_rayon/LICENSE-MIT
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2022 The Plonky2 Authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
13
maybe_rayon/README.md
Normal file
13
maybe_rayon/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
## License
|
||||
|
||||
Licensed under either of
|
||||
|
||||
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
||||
|
||||
at your option.
|
||||
|
||||
|
||||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
|
||||
202
plonky2/LICENSE-APACHE
Normal file
202
plonky2/LICENSE-APACHE
Normal file
@ -0,0 +1,202 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
21
plonky2/LICENSE-MIT
Normal file
21
plonky2/LICENSE-MIT
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2022 The Plonky2 Authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
20
plonky2/README.md
Normal file
20
plonky2/README.md
Normal file
@ -0,0 +1,20 @@
|
||||
# Plonky2
|
||||
|
||||
Plonky2 is a SNARK implementation based on techniques from PLONK and FRI. It is the successor of [Plonky](https://github.com/mir-protocol/plonky), which was based on PLONK and Halo.
|
||||
|
||||
Plonky2 is built for speed, and features a highly efficient recursive circuit. On a Macbook Pro, recursive proofs can be generated in about 170 ms.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
Licensed under either of
|
||||
|
||||
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
||||
|
||||
at your option.
|
||||
|
||||
|
||||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
|
||||
202
starky/LICENSE-APACHE
Normal file
202
starky/LICENSE-APACHE
Normal file
@ -0,0 +1,202 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
21
starky/LICENSE-MIT
Normal file
21
starky/LICENSE-MIT
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2022 The Plonky2 Authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
13
starky/README.md
Normal file
13
starky/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
## License
|
||||
|
||||
Licensed under either of
|
||||
|
||||
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
||||
|
||||
at your option.
|
||||
|
||||
|
||||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
|
||||
202
u32/LICENSE-APACHE
Normal file
202
u32/LICENSE-APACHE
Normal file
@ -0,0 +1,202 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
21
u32/LICENSE-MIT
Normal file
21
u32/LICENSE-MIT
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2022 The Plonky2 Authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
13
u32/README.md
Normal file
13
u32/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
## License
|
||||
|
||||
Licensed under either of
|
||||
|
||||
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
||||
|
||||
at your option.
|
||||
|
||||
|
||||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
|
||||
202
util/LICENSE-APACHE
Normal file
202
util/LICENSE-APACHE
Normal file
@ -0,0 +1,202 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
21
util/LICENSE-MIT
Normal file
21
util/LICENSE-MIT
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2022 The Plonky2 Authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
202
waksman/LICENSE-APACHE
Normal file
202
waksman/LICENSE-APACHE
Normal file
@ -0,0 +1,202 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
21
waksman/LICENSE-MIT
Normal file
21
waksman/LICENSE-MIT
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2022 The Plonky2 Authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
13
waksman/README.md
Normal file
13
waksman/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
## License
|
||||
|
||||
Licensed under either of
|
||||
|
||||
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
||||
|
||||
at your option.
|
||||
|
||||
|
||||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
|
||||
Loading…
x
Reference in New Issue
Block a user