Skip to content

Commit

Permalink
Add code for ec add and ec mul
Browse files Browse the repository at this point in the history
  • Loading branch information
AurelienFT committed Nov 14, 2024
1 parent d53e060 commit 273ffda
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 26 deletions.
5 changes: 5 additions & 0 deletions fuel-asm/src/panic_reason.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,11 @@ enum_from! {
BlobIdAlreadyUploaded = 0x37,
/// Active gas costs do not define the cost for this instruction.
GasCostNotDefined = 0x38,
/// The curve id is not supported.
UnsupportedCurveId = 0x39,
// TODO: Maybe add more different errors
/// Read alt_bn_128 curve point is invalid.
InvalidAltBn128Point = 0x3a,
}
}

Expand Down
1 change: 1 addition & 0 deletions fuel-vm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ anyhow = { version = "1.0", optional = true }
async-trait = "0.1"
backtrace = { version = "0.3", optional = true } # requires debug symbols to work
bitflags = { workspace = true }
bn = { package = "substrate-bn", version = "0.6", default-features = false }
derivative = "2.2"
derive_more = { version = "0.99", default-features = false, features = [
"display",
Expand Down
154 changes: 128 additions & 26 deletions fuel-vm/src/interpreter/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ use crate::{
error::SimpleResult,
};

use bn::{
AffineG1,
Fq,
Fr,
Group,
G1,
};
use fuel_crypto::{
Hasher,
Message,
Expand Down Expand Up @@ -92,7 +99,13 @@ where
)
}

pub(crate) fn ec_add(&mut self, a: Word, b: Word, c: Word, d: Word) -> SimpleResult<()> {
pub(crate) fn ec_add(
&mut self,
a: Word,
b: Word,
c: Word,
d: Word,
) -> SimpleResult<()> {
let owner = self.ownership_registers();
ec_add(
self.memory.as_mut(),
Expand All @@ -105,7 +118,13 @@ where
)
}

pub(crate) fn ec_mul(&mut self, a: Word, b: Word, c: Word, d: Word) -> SimpleResult<()> {
pub(crate) fn ec_mul(
&mut self,
a: Word,
b: Word,
c: Word,
d: Word,
) -> SimpleResult<()> {
let owner = self.ownership_registers();
ec_mul(
self.memory.as_mut(),
Expand All @@ -118,7 +137,13 @@ where
)
}

pub(crate) fn ec_pairing(&mut self, a: Word, b: Word, c: Word, d: Word) -> SimpleResult<()> {
pub(crate) fn ec_pairing(
&mut self,
a: Word,
b: Word,
c: Word,
d: Word,
) -> SimpleResult<()> {
let owner = self.ownership_registers();
ec_pairing(
self.memory.as_mut(),
Expand Down Expand Up @@ -242,38 +267,115 @@ pub(crate) fn sha256(
Ok(inc_pc(pc)?)
}

fn read_point_alt_bn_128(memory: &MemoryInstance, point_ptr: Word) -> SimpleResult<G1> {
let px = Fq::from_slice(memory.read(point_ptr, 32u64)?).map_err(|_| {
crate::error::PanicOrBug::Panic(fuel_tx::PanicReason::InvalidAltBn128Point)
})?;
let py = Fq::from_slice(
memory.read(
point_ptr
.checked_add(32)
.ok_or(crate::error::PanicOrBug::Panic(
fuel_tx::PanicReason::ArithmeticOverflow,
))?,
32u64,
)?,
)
.map_err(|_| {
crate::error::PanicOrBug::Panic(fuel_tx::PanicReason::InvalidAltBn128Point)
})?;

if px == Fq::zero() && py == Fq::zero() {
Ok(G1::zero())
} else {
AffineG1::new(px, py).map(Into::into).map_err(|_| {
crate::error::PanicOrBug::Panic(fuel_tx::PanicReason::InvalidAltBn128Point)
})
}
}

// TODO: When regid when imm ?
pub(crate) fn ec_add(
_memory: &mut MemoryInstance,
_owner: OwnershipRegisters,
_pc: RegMut<PC>,
_a: Word,
_b: Word,
_c: Word,
_d: Word,
memory: &mut MemoryInstance,
owner: OwnershipRegisters,
pc: RegMut<PC>,
dst: Word,
curve_id: Word,
point1_ptr: Word,
point2_ptr: Word,
) -> SimpleResult<()> {
todo!()
match curve_id {
0 => {
let point1 = read_point_alt_bn_128(memory, point1_ptr)?;
let point2 = read_point_alt_bn_128(memory, point2_ptr)?;
let mut output = [0u8; 64];
#[allow(clippy::arithmetic_side_effects)]
if let Some(sum) = AffineG1::from_jacobian(point1 + point2) {
sum.x().to_big_endian(&mut output[..32]).unwrap();
sum.y().to_big_endian(&mut output[32..]).unwrap();
}
memory.write_bytes(owner, dst, output)?;
}
_ => {
return Err(crate::error::PanicOrBug::Panic(
fuel_tx::PanicReason::UnsupportedCurveId,
))
}
}
Ok(inc_pc(pc)?)
}

pub(crate) fn ec_mul(
_memory: &mut MemoryInstance,
_owner: OwnershipRegisters,
_pc: RegMut<PC>,
_a: Word,
_b: Word,
_c: Word,
_d: Word,
memory: &mut MemoryInstance,
owner: OwnershipRegisters,
pc: RegMut<PC>,
dst: Word,
curve_id: Word,
point_ptr: Word,
scalar_ptr: Word,
) -> SimpleResult<()> {
todo!()
match curve_id {
0 => {
let point = read_point_alt_bn_128(memory, point_ptr)?;
let scalar =
Fr::from_slice(memory.read(scalar_ptr, 32u64)?).map_err(|_| {
crate::error::PanicOrBug::Panic(
fuel_tx::PanicReason::InvalidAltBn128Point,
)
})?;
let mut output = [0u8; 64];
#[allow(clippy::arithmetic_side_effects)]
if let Some(product) = AffineG1::from_jacobian(point * scalar) {
product.x().to_big_endian(&mut output[..32]).unwrap();
product.y().to_big_endian(&mut output[32..]).unwrap();
}
memory.write_bytes(owner, dst, output)?;
}
_ => {
return Err(crate::error::PanicOrBug::Panic(
fuel_tx::PanicReason::UnsupportedCurveId,
))
}
}
Ok(inc_pc(pc)?)
}

pub(crate) fn ec_pairing(
_memory: &mut MemoryInstance,
_owner: OwnershipRegisters,
_pc: RegMut<PC>,
_a: Word,
_b: Word,
_c: Word,
_d: Word,
pc: RegMut<PC>,
_success: Word,
curve_id: Word,
_num_points: Word,
_points_ptr: Word,
) -> SimpleResult<()> {
todo!()
}
match curve_id {
0 => {}
_ => {
return Err(crate::error::PanicOrBug::Panic(
fuel_tx::PanicReason::UnsupportedCurveId,
))
}
}
Ok(inc_pc(pc)?)
}

0 comments on commit 273ffda

Please sign in to comment.