Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] fp2 chip #739

Merged
merged 10 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions circuits/ecc/src/field_extension/fp2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ impl Fp2 {
Fp2 { c0, c1 }
}

pub fn new_var(builder: Rc<RefCell<ExprBuilder>>) -> ((usize, usize), Fp2) {
let (c0_idx, c0) = builder.borrow_mut().new_var();
let (c1_idx, c1) = builder.borrow_mut().new_var();
let fp2 = Fp2 {
c0: FieldVariable::from_var(builder.clone(), c0),
c1: FieldVariable::from_var(builder.clone(), c1),
};
((c0_idx, c1_idx), fp2)
}

pub fn save(&mut self) -> [usize; 2] {
let c0_idx = self.c0.save();
let c1_idx = self.c1.save();
Expand Down Expand Up @@ -145,6 +155,13 @@ impl Fp2 {
pub fn neg(&mut self) -> Fp2 {
self.int_mul([-1, 0])
}

pub fn select(flag_id: usize, a: &Fp2, b: &Fp2) -> Fp2 {
Fp2 {
c0: FieldVariable::select(flag_id, &a.c0, &b.c0),
c1: FieldVariable::select(flag_id, &a.c1, &b.c1),
}
}
}

#[cfg(test)]
Expand Down
13 changes: 13 additions & 0 deletions toolchain/instructions/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,19 @@ pub enum Fp12Opcode {
#[opcode_offset = 0x710]
#[repr(usize)]
#[allow(non_camel_case_types)]
pub enum Fp2Opcode {
ADD,
SUB,
MUL,
DIV,
}

#[derive(
Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, EnumCount, EnumIter, FromRepr, UsizeOpcode,
)]
#[opcode_offset = 0x720]
#[repr(usize)]
#[allow(non_camel_case_types)]
pub enum PairingOpcode {
MILLER_DOUBLE_STEP,
MILLER_DOUBLE_AND_ADD_STEP,
Expand Down
121 changes: 116 additions & 5 deletions vm/src/arch/chip_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ use crate::{
arch::{AxVmChip, AxVmExecutor, ExecutionBus, ExecutorName, VmConfig},
intrinsics::{
ecc::{
fp2::{Fp2AddSubChip, Fp2MulDivChip},
pairing::{
EcLineMul013By013Chip, EcLineMul023By023Chip, EcLineMulBy01234Chip,
EcLineMulBy02345Chip, MillerDoubleAndAddStepChip, MillerDoubleStepChip,
Expand Down Expand Up @@ -998,6 +999,7 @@ impl VmConfig {
executors.insert(global_opcode_idx, chip.clone().into());
chips.push(AxVmChip::Executor(chip.into()));
}

ExecutorName::MillerDoubleAndAddStepRv32_48 => {
let chip = Rc::new(RefCell::new(MillerDoubleAndAddStepChip::new(
Rv32VecHeapAdapterChip::<F, 2, 12, 36, 16, 16>::new(
Expand All @@ -1013,6 +1015,66 @@ impl VmConfig {
executors.insert(global_opcode_idx, chip.clone().into());
chips.push(AxVmChip::Executor(chip.into()));
}
ExecutorName::Fp2AddSubRv32_32 => {
let chip = Rc::new(RefCell::new(Fp2AddSubChip::new(
Rv32VecHeapAdapterChip::<F, 2, 1, 1, 32, 32>::new(
execution_bus,
program_bus,
memory_controller.clone(),
bitwise_lookup_chip.clone(),
),
memory_controller.clone(),
config32,
class_offset,
)));
executors.insert(global_opcode_idx, chip.clone().into());
chips.push(AxVmChip::Executor(chip.into()));
}
ExecutorName::Fp2MulDivRv32_32 => {
let chip = Rc::new(RefCell::new(Fp2MulDivChip::new(
Rv32VecHeapAdapterChip::<F, 2, 1, 1, 32, 32>::new(
execution_bus,
program_bus,
memory_controller.clone(),
bitwise_lookup_chip.clone(),
),
memory_controller.clone(),
config32,
class_offset,
)));
executors.insert(global_opcode_idx, chip.clone().into());
chips.push(AxVmChip::Executor(chip.into()));
}
ExecutorName::Fp2AddSubRv32_48 => {
let chip = Rc::new(RefCell::new(Fp2AddSubChip::new(
Rv32VecHeapAdapterChip::<F, 2, 3, 3, 16, 16>::new(
execution_bus,
program_bus,
memory_controller.clone(),
bitwise_lookup_chip.clone(),
),
memory_controller.clone(),
config48,
class_offset,
)));
executors.insert(global_opcode_idx, chip.clone().into());
chips.push(AxVmChip::Executor(chip.into()));
}
ExecutorName::Fp2MulDivRv32_48 => {
let chip = Rc::new(RefCell::new(Fp2MulDivChip::new(
Rv32VecHeapAdapterChip::<F, 2, 3, 3, 16, 16>::new(
execution_bus,
program_bus,
memory_controller.clone(),
bitwise_lookup_chip.clone(),
),
memory_controller.clone(),
config48,
class_offset,
)));
executors.insert(global_opcode_idx, chip.clone().into());
chips.push(AxVmChip::Executor(chip.into()));
}
_ => unreachable!("Unsupported executor"),
}
}
Expand Down Expand Up @@ -1239,37 +1301,86 @@ fn gen_pairing_executor_tuple(
.iter()
.enumerate()
.flat_map(|(i, curve)| {
let class_offset = PairingOpcode::default_offset() + i * PairingOpcode::COUNT;
let pairing_class_offset = PairingOpcode::default_offset() + i * PairingOpcode::COUNT;
let fp2_class_offset = Fp2Opcode::default_offset() + i * Fp2Opcode::COUNT;
let bytes = curve.prime().bits().div_ceil(8);
if bytes <= 32 {
vec![
(
PairingOpcode::MILLER_DOUBLE_STEP as usize,
class_offset,
pairing_class_offset,
ExecutorName::MillerDoubleStepRv32_32,
curve.prime(),
),
(
PairingOpcode::MILLER_DOUBLE_AND_ADD_STEP as usize,
class_offset,
pairing_class_offset,
ExecutorName::MillerDoubleAndAddStepRv32_32,
curve.prime(),
),
(
Fp2Opcode::ADD as usize,
fp2_class_offset,
ExecutorName::Fp2AddSubRv32_32,
curve.prime(),
),
(
Fp2Opcode::SUB as usize,
fp2_class_offset,
ExecutorName::Fp2AddSubRv32_32,
curve.prime(),
),
(
Fp2Opcode::MUL as usize,
fp2_class_offset,
ExecutorName::Fp2MulDivRv32_32,
curve.prime(),
),
(
Fp2Opcode::DIV as usize,
fp2_class_offset,
ExecutorName::Fp2MulDivRv32_32,
curve.prime(),
),
]
} else if bytes <= 48 {
vec![
(
PairingOpcode::MILLER_DOUBLE_STEP as usize,
class_offset,
pairing_class_offset,
ExecutorName::MillerDoubleStepRv32_48,
curve.prime(),
),
(
PairingOpcode::MILLER_DOUBLE_AND_ADD_STEP as usize,
class_offset,
pairing_class_offset,
ExecutorName::MillerDoubleAndAddStepRv32_48,
curve.prime(),
),
(
Fp2Opcode::ADD as usize,
fp2_class_offset,
ExecutorName::Fp2AddSubRv32_48,
curve.prime(),
),
(
Fp2Opcode::SUB as usize,
fp2_class_offset,
ExecutorName::Fp2AddSubRv32_48,
curve.prime(),
),
(
Fp2Opcode::MUL as usize,
fp2_class_offset,
ExecutorName::Fp2MulDivRv32_48,
curve.prime(),
),
(
Fp2Opcode::DIV as usize,
fp2_class_offset,
ExecutorName::Fp2MulDivRv32_48,
curve.prime(),
),
]
} else {
panic!("curve {:?} is not supported", curve);
Expand Down
6 changes: 6 additions & 0 deletions vm/src/arch/chips.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::{
arch::ExecutionState,
intrinsics::{
ecc::{
fp2::{Fp2AddSubChip, Fp2MulDivChip},
pairing::{
EcLineMul013By013Chip, EcLineMul023By023Chip, EcLineMulBy01234Chip,
EcLineMulBy02345Chip, MillerDoubleAndAddStepChip, MillerDoubleStepChip,
Expand Down Expand Up @@ -122,6 +123,11 @@ pub enum AxVmExecutor<F: PrimeField32> {
EcAddNeRv32_6x16(Rc<RefCell<EcAddNeChip<F, 6, 16>>>),
EcDoubleRv32_6x16(Rc<RefCell<EcDoubleChip<F, 6, 16>>>),
// Pairing:
// Fp2 for 32-bytes or 48-bytes prime.
Fp2AddSubRv32_32(Rc<RefCell<Fp2AddSubChip<F, 1, 32>>>),
Fp2AddSubRv32_48(Rc<RefCell<Fp2AddSubChip<F, 3, 16>>>),
Fp2MulDivRv32_32(Rc<RefCell<Fp2MulDivChip<F, 1, 32>>>),
Fp2MulDivRv32_48(Rc<RefCell<Fp2MulDivChip<F, 3, 16>>>),
/// Only for BN254 for now
EcLineMul013By013(Rc<RefCell<EcLineMul013By013Chip<F, 4, 10, 32>>>),
/// Only for BN254 for now
Expand Down
Loading
Loading