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

Add is_infinity field to secp256 point struct #828

Merged
merged 14 commits into from
Oct 8, 2024
1 change: 0 additions & 1 deletion src/libfuncs/starknet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2981,7 +2981,6 @@ pub fn build_sha256_process_block_syscall<'ctx, 'this>(
metadata: &mut MetadataStorage,
info: &SignatureOnlyConcreteLibfunc,
) -> Result<()> {
// todo: do
// Extract self pointer.
let ptr = entry
.append_operation(llvm::load(
Expand Down
4 changes: 4 additions & 0 deletions src/starknet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,19 @@ pub struct TxInfo {
}

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[repr(C, align(16))]
edg-l marked this conversation as resolved.
Show resolved Hide resolved
pub struct Secp256k1Point {
pub x: U256,
pub y: U256,
pub is_infinity: bool,
}

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[repr(C, align(16))]
edg-l marked this conversation as resolved.
Show resolved Hide resolved
pub struct Secp256r1Point {
pub x: U256,
pub y: U256,
pub is_infinity: bool,
}

pub trait StarknetSyscallHandler {
Expand Down
126 changes: 105 additions & 21 deletions src/starknet_stub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,11 @@ impl StarknetSyscallHandler for &mut StubSyscallHandler {
);

if bool::from(point.is_some()) {
Ok(Some(Secp256k1Point { x, y }))
Ok(Some(Secp256k1Point {
x,
y,
is_infinity: false,
}))
} else {
Ok(None)
}
Expand All @@ -302,6 +306,21 @@ impl StarknetSyscallHandler for &mut StubSyscallHandler {
_remaining_gas: &mut u128,
) -> SyscallResult<Secp256k1Point> {
tracing::debug!("called");

if p0.is_infinity || p1.is_infinity {
if p1.is_infinity {
return Ok(p0);
} else if p0.is_infinity {
return Ok(p1);
} else {
return Ok(Secp256k1Point {
x: U256 { hi: 0, lo: 0 },
y: U256 { hi: 0, lo: 0 },
is_infinity: true,
});
}
}

// The inner unwraps should be unreachable because the iterator we provide has the expected
// number of bytes. The outer unwraps depend on the felt values, which should be valid since
// they'll be provided by secp256 syscalls.
Expand Down Expand Up @@ -349,8 +368,9 @@ impl StarknetSyscallHandler for &mut StubSyscallHandler {
let p = p0 + p1;

let p = p.to_encoded_point(false);
let (x, y) = match p.coordinates() {
Coordinates::Uncompressed { x, y } => (x, y),
let (x, y, is_infinity) = match p.coordinates() {
Coordinates::Uncompressed { x, y } => (x.as_slice(), y.as_slice(), false),
Coordinates::Identity => ([0u8; 32].as_slice(), [0; 32].as_slice(), true),
_ => {
// This should be unreachable because we explicitly asked for the uncompressed
// encoding.
Expand All @@ -360,8 +380,8 @@ impl StarknetSyscallHandler for &mut StubSyscallHandler {

// The following two unwraps should be safe because the array always has 32 bytes. The other
// four are definitely safe because the slicing guarantees its length to be the right one.
let x: [u8; 32] = x.as_slice().try_into().unwrap();
let y: [u8; 32] = y.as_slice().try_into().unwrap();
let x: [u8; 32] = x.try_into().unwrap();
let y: [u8; 32] = y.try_into().unwrap();
Ok(Secp256k1Point {
x: U256 {
hi: u128::from_be_bytes(x[0..16].try_into().unwrap()),
Expand All @@ -371,27 +391,39 @@ impl StarknetSyscallHandler for &mut StubSyscallHandler {
hi: u128::from_be_bytes(y[0..16].try_into().unwrap()),
lo: u128::from_be_bytes(y[16..32].try_into().unwrap()),
},
is_infinity,
})
}

#[instrument(skip(self))]
fn secp256k1_mul(
&mut self,
p: Secp256k1Point,
p_arg: Secp256k1Point,
m: U256,
_remaining_gas: &mut u128,
) -> SyscallResult<Secp256k1Point> {
// The inner unwrap should be unreachable because the iterator we provide has the expected
// number of bytes. The outer unwrap depends on the felt values, which should be valid since
// they'll be provided by secp256 syscalls.

let p = k256::ProjectivePoint::from_encoded_point(
&k256::EncodedPoint::from_affine_coordinates(
&GenericArray::from_exact_iter(
p.x.hi.to_be_bytes().into_iter().chain(p.x.lo.to_be_bytes()),
p_arg
.x
.hi
.to_be_bytes()
.into_iter()
.chain(p_arg.x.lo.to_be_bytes()),
)
.unwrap(),
&GenericArray::from_exact_iter(
p.y.hi.to_be_bytes().into_iter().chain(p.y.lo.to_be_bytes()),
p_arg
.y
.hi
.to_be_bytes()
.into_iter()
.chain(p_arg.y.lo.to_be_bytes()),
)
.unwrap(),
false,
edg-l marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -414,8 +446,9 @@ impl StarknetSyscallHandler for &mut StubSyscallHandler {
let p = p * m;

let p = p.to_encoded_point(false);
let (x, y) = match p.coordinates() {
Coordinates::Uncompressed { x, y } => (x, y),
let (x, y, is_infinity) = match p.coordinates() {
Coordinates::Uncompressed { x, y } => (x.as_slice(), y.as_slice(), false),
Coordinates::Identity => ([0u8; 32].as_slice(), [0; 32].as_slice(), true),
_ => {
// This should be unreachable because we explicitly asked for the uncompressed
// encoding.
Expand All @@ -425,8 +458,8 @@ impl StarknetSyscallHandler for &mut StubSyscallHandler {

// The following two unwraps should be safe because the array always has 32 bytes. The other
// four are definitely safe because the slicing guarantees its length to be the right one.
let x: [u8; 32] = x.as_slice().try_into().unwrap();
let y: [u8; 32] = y.as_slice().try_into().unwrap();
let x: [u8; 32] = x.try_into().unwrap();
let y: [u8; 32] = y.try_into().unwrap();
Ok(Secp256k1Point {
x: U256 {
hi: u128::from_be_bytes(x[0..16].try_into().unwrap()),
Expand All @@ -436,6 +469,7 @@ impl StarknetSyscallHandler for &mut StubSyscallHandler {
hi: u128::from_be_bytes(y[0..16].try_into().unwrap()),
lo: u128::from_be_bytes(y[16..32].try_into().unwrap()),
},
is_infinity,
})
}

Expand Down Expand Up @@ -486,6 +520,7 @@ impl StarknetSyscallHandler for &mut StubSyscallHandler {
hi: u128::from_be_bytes(y[0..16].try_into().unwrap()),
lo: u128::from_be_bytes(y[16..32].try_into().unwrap()),
},
is_infinity: false,
}))
} else {
Ok(None)
Expand Down Expand Up @@ -527,7 +562,11 @@ impl StarknetSyscallHandler for &mut StubSyscallHandler {
);

if bool::from(point.is_some()) {
Ok(Some(Secp256r1Point { x, y }))
Ok(Some(Secp256r1Point {
x,
y,
is_infinity: false,
}))
} else {
Ok(None)
}
Expand All @@ -541,6 +580,21 @@ impl StarknetSyscallHandler for &mut StubSyscallHandler {
_remaining_gas: &mut u128,
) -> SyscallResult<Secp256r1Point> {
tracing::debug!("called");

if p0.is_infinity || p1.is_infinity {
if p1.is_infinity {
return Ok(p0);
} else if p0.is_infinity {
return Ok(p1);
} else {
return Ok(Secp256r1Point {
x: U256 { hi: 0, lo: 0 },
y: U256 { hi: 0, lo: 0 },
is_infinity: true,
});
}
}

// The inner unwraps should be unreachable because the iterator we provide has the expected
// number of bytes. The outer unwraps depend on the felt values, which should be valid since
// they'll be provided by secp256 syscalls.
Expand Down Expand Up @@ -610,6 +664,7 @@ impl StarknetSyscallHandler for &mut StubSyscallHandler {
hi: u128::from_be_bytes(y[0..16].try_into().unwrap()),
lo: u128::from_be_bytes(y[16..32].try_into().unwrap()),
},
is_infinity: false,
})
}

Expand Down Expand Up @@ -652,8 +707,9 @@ impl StarknetSyscallHandler for &mut StubSyscallHandler {

let p = p * m;
let p = p.to_encoded_point(false);
let (x, y) = match p.coordinates() {
Coordinates::Uncompressed { x, y } => (x, y),
let (x, y, is_infinity) = match p.coordinates() {
Coordinates::Uncompressed { x, y } => (x.as_slice(), y.as_slice(), false),
Coordinates::Identity => ([0u8; 32].as_slice(), [0; 32].as_slice(), true),
_ => {
// This should be unreachable because we explicitly asked for the uncompressed
// encoding.
Expand All @@ -663,8 +719,8 @@ impl StarknetSyscallHandler for &mut StubSyscallHandler {

// The following two unwraps should be safe because the array always has 32 bytes. The other
// four are definitely safe because the slicing guarantees its length to be the right one.
let x: [u8; 32] = x.as_slice().try_into().unwrap();
let y: [u8; 32] = y.as_slice().try_into().unwrap();
let x: [u8; 32] = x.try_into().unwrap();
let y: [u8; 32] = y.try_into().unwrap();
Ok(Secp256r1Point {
x: U256 {
hi: u128::from_be_bytes(x[0..16].try_into().unwrap()),
Expand All @@ -674,6 +730,7 @@ impl StarknetSyscallHandler for &mut StubSyscallHandler {
hi: u128::from_be_bytes(y[0..16].try_into().unwrap()),
lo: u128::from_be_bytes(y[16..32].try_into().unwrap()),
},
is_infinity,
})
}

Expand Down Expand Up @@ -712,6 +769,7 @@ impl StarknetSyscallHandler for &mut StubSyscallHandler {
hi: u128::from_be_bytes(y[0..16].try_into().unwrap()),
lo: u128::from_be_bytes(y[16..32].try_into().unwrap()),
},
is_infinity: false,
}))
} else {
Ok(None)
Expand Down Expand Up @@ -853,6 +911,7 @@ mod tests {
hi: 75181762170223969696219813306313470806,
lo: 134255467439736302886468555755295925874,
},
is_infinity: false,
};

let mut test_syscall_handler = StubSyscallHandler::default();
Expand Down Expand Up @@ -889,7 +948,11 @@ mod tests {

assert_eq!(
test_syscall_handler.secp256k1_new(x, y, &mut 10).unwrap(),
Some(Secp256k1Point { x, y })
Some(Secp256k1Point {
x,
y,
is_infinity: false
})
);
}

Expand Down Expand Up @@ -924,6 +987,7 @@ mod tests {
lo: 336417762351022071123394393598455764152,
hi: 96009999919712310848645357523629574312,
},
is_infinity: false,
};

let p2 = p1;
Expand All @@ -940,6 +1004,7 @@ mod tests {
lo: 329597642124196932058042157271922763050,
hi: 35730324229579385338853513728577301230,
},
is_infinity: false,
};
assert_eq!(p3, p1_double);
assert_eq!(
Expand All @@ -959,6 +1024,7 @@ mod tests {
lo: 134255467439736302886468555755295925874,
hi: 75181762170223969696219813306313470806,
},
is_infinity: false,
};
assert_eq!(
test_syscall_handler.secp256k1_add(p1, p3, &mut 10).unwrap(),
Expand Down Expand Up @@ -998,6 +1064,7 @@ mod tests {
lo: 68974579539311638391577168388077592842,
hi: 26163136114030451075775058782541084873,
},
is_infinity: false
}
);
}
Expand Down Expand Up @@ -1028,6 +1095,7 @@ mod tests {
lo: 271307787381626825071797439039395650341,
hi: 314119230806908012387599548649227126582,
},
is_infinity: false
}
);
}
Expand Down Expand Up @@ -1062,7 +1130,11 @@ mod tests {
.secp256r1_new(x, y, &mut 10)
.unwrap()
.unwrap(),
Secp256r1Point { x, y }
Secp256r1Point {
x,
y,
is_infinity: false
}
);
}

Expand Down Expand Up @@ -1094,6 +1166,7 @@ mod tests {
lo: 111045440647474106186537215379882575585,
hi: 118910939004298029402109603132816090461,
},
is_infinity: false,
};

let p2 = p1;
Expand All @@ -1110,6 +1183,7 @@ mod tests {
lo: 231570843221643745062297421862629788481,
hi: 84249534056490759701994051847937833933,
},
is_infinity: false,
};
assert_eq!(p3, p1_double);
assert_eq!(
Expand All @@ -1129,6 +1203,7 @@ mod tests {
lo: 282344931843342117515389970197013120959,
hi: 178681203065513270100417145499857169664,
},
is_infinity: false,
};
assert_eq!(
test_syscall_handler.secp256r1_add(p1, p3, &mut 10).unwrap(),
Expand Down Expand Up @@ -1162,7 +1237,11 @@ mod tests {
.secp256r1_get_point_from_x(x, true, &mut 10)
.unwrap()
.unwrap(),
Secp256r1Point { x, y }
Secp256r1Point {
x,
y,
is_infinity: false
}
);
}

Expand All @@ -1186,7 +1265,11 @@ mod tests {
.secp256r1_get_point_from_x(x, false, &mut 10)
.unwrap()
.unwrap(),
Secp256r1Point { x, y }
Secp256r1Point {
x,
y,
is_infinity: false
}
);
}

Expand Down Expand Up @@ -1214,6 +1297,7 @@ mod tests {
lo: 221371427837412271565447410779117722274,
hi: 229236926352692519791101729645429586206,
},
is_infinity: false,
};

let mut test_syscall_handler = StubSyscallHandler::default();
Expand Down
2 changes: 2 additions & 0 deletions src/types/starknet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ pub fn build_secp256_point<'ctx>(
&[
IntegerType::new(context, 128).into(),
IntegerType::new(context, 128).into(),
IntegerType::new(context, 128).into(),
],
false,
),
Expand All @@ -180,6 +181,7 @@ pub fn build_secp256_point<'ctx>(
],
false,
),
IntegerType::new(context, 1).into(),
],
false,
))
Expand Down
Loading
Loading